题意:在一个街道网格中有若干个银行,现在有小偷去偷,在偷完钱后由于不能被警察抓到所有任意两个小偷不能走同一条街道(点和边都不行)逃跑,问你是否能把所有的银行都偷到。

思路:这道题就是最大流,先建图后套模版就行了。借这道题用了邝大神的sap模版果断效率很高,对于这道题由于点的容量有限制所以需要拆点,然而一开始我没有读清楚题意所以没有拆点导致怎么也算不对。。。后来一想不对劲改过来立马ac了。首先每个点拆成两个结点(一个专门连出边,一个入边)从出边点连一条边指向入边点流量为1。然后在网格之间建立双向变。最后我们设立一个源点,从原点出发到所有银行流量为1表示有小偷去偷,然后再设立一个汇点使所有边上的结点都指向它。

见图过程到此为止接下来就是套模板,判断流量是否等于银行数。

代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <utility>
  7 #include <queue>
  8 #include <stack>
  9 #include <vector>
 10
 11 using namespace std;
 12
 13 int n, sa, sb, m;
 14
 15 //sap by kuangbin
 16 const int MAXN = 100010;//点数的最大值
 17 const int MAXM = 400010;//边数的最大值
 18 const int INF = 0x3f3f3f3f;
 19 struct Edge
 20 {
 21     int to,next,cap,flow;
 22 } edge[MAXM]; //注意是MAXM
 23 int tol;
 24 int head[MAXN];
 25 int gap[MAXN],dep[MAXN],cur[MAXN];
 26 void init()
 27 {
 28     tol = 0;
 29     memset(head,-1,sizeof(head));
 30 }
 31 void addedge(int u,int v,int w,int rw = 0)
 32 {
 33     edge[tol].to = v;
 34     edge[tol].cap = w;
 35     edge[tol].flow = 0;
 36     edge[tol].next = head[u];
 37     head[u] = tol++;
 38     edge[tol].to = u;
 39     edge[tol].cap = rw;
 40     edge[tol].flow = 0;
 41     edge[tol].next = head[v];
 42     head[v] = tol++;
 43 }
 44 int Q[MAXN];
 45 void BFS(int start,int end)
 46 {
 47     memset(dep,-1,sizeof(dep));
 48     memset(gap,0,sizeof(gap));
 49     gap[0] = 1;
 50     int front = 0, rear = 0;
 51     dep[end] = 0;
 52     Q[rear++] = end;
 53     while(front != rear)
 54     {
 55         int u = Q[front++];
 56         for(int i = head[u]; i != -1; i = edge[i].next)
 57         {
 58             int v = edge[i].to;
 59             if(dep[v] != -1)continue;
 60             Q[rear++] = v;
 61             dep[v] = dep[u] + 1;
 62             gap[dep[v]]++;
 63         }
 64     }
 65 }
 66 int S[MAXN];
 67 int sap(int start,int end,int N)
 68 {
 69     BFS(start,end);
 70     memcpy(cur,head,sizeof(head));
 71     int top = 0;
 72     int u = start;
 73     int ans = 0;
 74     while(dep[start] < N)
 75     {
 76         if(u == end)
 77         {
 78             int Min = INF;
 79             int inser;
 80             for(int i = 0; i < top; i++)
 81                 if(Min > edge[S[i]].cap - edge[S[i]].flow)
 82                 {
 83                     Min = edge[S[i]].cap - edge[S[i]].flow;
 84                     inser = i;
 85                 }
 86             for(int i = 0; i < top; i++)
 87             {
 88                 edge[S[i]].flow += Min;
 89                 edge[S[i]^1].flow -= Min;
 90             }
 91             ans += Min;
 92             top = inser;
 93             u = edge[S[top]^1].to;
 94             continue;
 95         }
 96         bool flag = false;
 97         int v;
 98         for(int i = cur[u]; i != -1; i = edge[i].next)
 99         {
100             v = edge[i].to;
101             if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])
102             {
103
104                 flag = true;
105                 cur[u] = i;
106                 break;
107             }
108         }
109         if(flag)
110         {
111             S[top++] = cur[u];
112             u = v;
113             continue;
114         }
115         int Min = N;
116         for(int i = head[u]; i != -1; i = edge[i].next)
117             if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
118             {
119                 Min = dep[edge[i].to];
120                 cur[u] = i;
121             }
122         gap[dep[u]]--;
123         if(!gap[dep[u]])return ans;
124         dep[u] = Min + 1;
125         gap[dep[u]]++;
126         if(u != start)u = edge[S[--top]^1].to;
127     }
128     return ans;
129 }
130
131 inline int ch(int x, int y, int isout){return (isout?(x*sb+y):(x*sb+y+sa*sb));}
132 void buildmap()
133 {
134     init();
135     n = sa*sb*2+2;
136     for(int i=1; i<=sa; i++)
137     for(int j=1; j<=sb; j++)
138     addedge(ch(i,j,0), ch(i,j,1),1);
139     for(int i=1; i<=sa; i++)
140     {
141         for(int j=1; j<sb; j++)
142         {
143             addedge(ch(i,j,1), ch(i,j+1,0), 1);
144             addedge(ch(i,j+1,1), ch(i,j,0), 1);
145         }
146     }
147     for(int i=1; i<sa; i++)
148     {
149         for(int j=1; j<=sb; j++)
150         {
151             addedge(ch(i,j,1), ch(i+1,j,0), 1);
152             addedge(ch(i+1,j,1), ch(i,j,0), 1);
153         }
154     }
155     for(int i=1; i<=sb; i++)
156     {
157         addedge(ch(1,i,1), n-1, 1);
158         addedge(ch(sa,i,1), n-1, 1);
159     }
160     for(int i=2; i<sa; i++)
161     {
162         addedge(ch(i,1,1), n-1, 1);
163         addedge(ch(i,sb,1), n-1, 1);
164     }
165 }
166
167 int main()
168 {
169 //    freopen("in.txt", "r", stdin);
170
171     int T, a, b;
172     scanf("%d", &T);
173     while(T--)
174     {
175         scanf("%d%d%d", &sa, &sb, &m);
176         buildmap();
177         for(int i=0; i<m; i++)
178         {
179             scanf("%d%d", &a, &b);
180             addedge(0, ch(a,b,0), 1);
181         }
182         int ans = sap(0,n-1, n);
183         if(ans==m)printf("possible\n");
184         else printf("not possible\n");
185     }
186     return 0;
187 }

View Code

转载于:https://www.cnblogs.com/shu-xiaohao/p/3491526.html

uva 563(最大流)相关推荐

  1. Crimewave UVA - 563(最大流)

    传送门:QAQ 题意:就是给你一个二维平面图,然后图上有若干个整数点,问你是否可能每个点都到达边界并且图上任意一点只能被一个点经过且经过一次. 思路:因为每个点只能经过一次,所以我们将每个点拆成两个点 ...

  2. Matrix Decompressing UVA - 11082 最大流 + 输出方案

    传送门 文章目录 题意: 思路: 题意: 给出前iii行的元素和A[i]A[i]A[i],前jjj列的元素B[j]B[j]B[j],让你构造一个矩阵使得其满足前iii行的元素和是A[i]A[i]A[i ...

  3. 初学者acm的练习题指南

    上机练习题参考题 忘了在哪找的啦~~希望对大家有帮助呦 <!--[if !supportLists]-->1.    <!--[endif]-->Programming Bas ...

  4. mac下查看mysql端口被占用_MAC下查看端口占用并杀死进程

    Eclipse在Run on Server时,Tomcat是开启的,但是报错,显示8080.8005和8009端口被占用 终端输入 查看所有开启的端口 sudo lsof -i -P | grep - ...

  5. UVA - 10480 Sabotage(最小割-最大流+输出割边)

    题目链接:点击查看 题目大意:给出一张无向图,1为起点,2为终点,删除每条边都需要权值wi,题目需要求将起点与终点分割为两个部分的最小花费,并且输出方案 题目分析:如果不让输出方案的话就是一个裸的最大 ...

  6. UVA - 820 Internet Bandwidth(最大流模板题)

    题目: 思路: 直接套最大流的模板就OK了,注意一下输出的格式. 代码: #include <bits/stdc++.h> #define inf 0x3f3f3f3f #define M ...

  7. uva 10594(最小费用最大流)

    题意:在一个无向网络中,告诉你边的容量与费用.现在需要传送d个数据问你你否能传送成功,若成功则最小费用是多少. 思路:显然是最小费用最大流问题,这道题的见图比较简单.只需要添加一个原点费用为D指向1就 ...

  8. UVa 10806 Dijkstra,Dijkstra(最小费用最大流)

    裸的费用流.往返就相当于从起点走两条路到终点. 按题意建图,将距离设为费用,流量设为1.然后增加2个点,一个连向节点1,流量=2,费用=0;结点n连一条同样的弧,然后求解最小费用最大流.当且仅当最大流 ...

  9. UVA 10480 - Sabotage (最大流)

    这道题的意思要把一个图分成两部分,要把点1和点2分开.隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边. 这题很明显是最小割,也就是最大流.把1当成源点,2当成汇点. 问题是要求最小割应该隔 ...

  10. uva 753(网络流最大流)

    网络流最大流问题,这里使s=0,使s与所有的插头相连,最大通量为1,然后插头和转换器相连,最大通量为1,转换器和转换器相连,因为有无限个,所以为inf,然后转换器和插座连,最大通量为1,插座和t相连, ...

最新文章

  1. apache 2.4.12 + tomcat 7.0.61 + jk connectors 1.2.40实现tomcat负载均衡集群
  2. iOS开发中的 地区转经纬 经纬度转地区
  3. 用递归的方法求s = k! + n! / m!的值
  4. python如何编程-终于发现怎么自学python编程
  5. python函数的使用方法_百度资讯搜索_python函数的使用方法
  6. wrapper php,PHP流Streams、包装器wrapper概念与用法实例详解
  7. 关于mysql叙述中错误的是什么_以下关于MySQL的叙述中,错误的是( )。_学小易找答案...
  8. 一个项目部署多个节点会导致锁失效么_不为人知的分布式锁实现,全都在这里了
  9. java excel 转 图片_Java中excel转换为jpg/png图片 采用aspose-cells-18.6.jar
  10. 抖音热门小视频 视频的md5查看器
  11. linux下oracle 9204 soft only,在CentOS4.3(x86_64)上安装Oracle9204 for linux(x86_64)
  12. 程序员养生-人体白发的机制及治疗、调养恢复
  13. 从k8s.gcr.io拉取镜像
  14. TemplateDoesNotExist错误之伤
  15. PhotoShop中的自由变换UI实现
  16. python中numpy模块下的np.clip()的用法
  17. ARM发布全新16纳米A72架构
  18. 《灵飞经》3·印神无双 第十三章 剑奕星斗 2
  19. java 什么是多态性_Java多态性理解
  20. Chrome谷歌浏览器弹框提示:代理要求提供用户名与密码

热门文章

  1. pandas小记:pandas汇总统计函数
  2. java时间格式大全_Java时间格式转换大全
  3. 小瓦怕扫地机器人_小瓦扫地机器人青春版评测:便宜有好货
  4. python爬虫可以做哪些好玩的地方_如何快速的找到好玩的旅游景点信息?Python爬虫帮你轻松解决...
  5. 查看mysql 表 被人删除_我的数据库中有一表总是被什么人删掉数据?我如何查出来是谁做的?...
  6. Android报错: Caused by: java.lang.ClassCastException: com.github.mikephil.charting.charts.PieChart can
  7. SQL Server-【知识与实战VIII】触发器(中)
  8. JSP — 如何设置jsp中cookie的过期时间
  9. RK3288_Android7.1调试RTC总结(二)
  10. 七. 并发编程 (进程队列)