HDU_3313_Key_Vertex(最小割)
2015-06-18 11:25
375 查看
题意:已给有向图,给定起点和终点S,T,问图中有多少个点去掉可以使S T不可达
思路:
按常规思路就是找一条最短路,最短路之外的所有点不符合条件,然后在最短路上搞搞就好了
为了加深一下最小割的理解就用最小割写了此题
拆点,拆点之间连容量为1的边,有向边连inf的边,最大流一下,显然关键点的拆点间的流是满流而且必须是最小割。
然后就从满流+最小割这两点判断就可以辣,若u -> v 不是最小割,那么残余网络上S必然可达v,所以在残余网络上bfsS的可达点。
思路:
按常规思路就是找一条最短路,最短路之外的所有点不符合条件,然后在最短路上搞搞就好了
为了加深一下最小割的理解就用最小割写了此题
拆点,拆点之间连容量为1的边,有向边连inf的边,最大流一下,显然关键点的拆点间的流是满流而且必须是最小割。
然后就从满流+最小割这两点判断就可以辣,若u -> v 不是最小割,那么残余网络上S必然可达v,所以在残余网络上bfsS的可达点。
/* ********************************************** Auther: kalili Created Time: 2015/6/17 18:10:30 File Name : HDU_3313_Key_Vertex最小割.cpp *********************************************** */ //Accepted 3313 2386MS 19136K 5692 B C++ #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <list> #include <map> #include <set> #include <sstream> #include <string> #include <vector> #include <cstdio> #include <ctime> #include <bitset> #include <algorithm> #define SZ(x) ((int)(x).size()) #define ALL(v) (v).begin(), (v).end() #define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i) #define REP(i,n) for ( int i=1; i<=int(n); i++ ) using namespace std; const int inf = 0x3f3f3f3f; const int N = 200000 +100; const int M = 300000*10+10; struct Edge { int v,w,nxt; Edge(){} Edge(int v,int w,int nxt) : v(v),w(w),nxt(nxt) {} }es[M]; int n,m; int head ; int cnt; void inline add_edge(int u,int v,int w) { es[cnt]=Edge(v,w,head[u]); head[u]=cnt++; es[cnt]=Edge(u,0,head[v]); head[v]=cnt++; } int s,g; int h ,q ,tail; bool makeh(int s,int g) { memset(h,0,sizeof(h)); h[s]=1; tail=0; q[tail++]=s; for(int i=0;i<tail;i++) { int u = q[i]; if(u == g) return true; for(int i = head[u];~i;i = es[i].nxt) { int v = es[i].v,w = es[i].w; if(w&&h[v] == 0) q[tail++]=v,h[v] = h[u]+1; } } return false; } int dfs(int u,int g,int maxf) { if(u == g) return maxf; int ans=0; for(int i = head[u];~i;i = es[i].nxt) { int v = es[i].v,w = es[i].w; if(w&&h[v] == h[u]+1) { int f = dfs(v,g,min(maxf-ans,w)); ans += f; es[i].w -= f; es[i^1].w += f; if(ans == maxf) return ans; } } if(ans == 0) h[u]=-1; return ans; } int Dinic(int s,int g) { int ans=0; while(makeh(s,g)) ans+=dfs(s,g,inf); return ans; } bool vis ; int que ,top; void bfs(int src) { que[top++] = src; vis[src]=1; for(int i = 0;i < top; i++) { int u=que[i]; for(int i = head[u]; ~i ;i = es[i].nxt) { int v = es[i].v,w = es[i].w; if(w&&vis[v] == 0) que[top++]=v,vis[v]=1; } } } void ini() { cnt=0; memset(head,-1,sizeof(head)); } int main() { while(~scanf("%d%d",&n,&m)) { ini(); REP(i,m) { int u,v; scanf("%d%d",&u,&v); add_edge(u+n,v,inf); } scanf("%d%d",&s,&g); for(int i=0;i<n;i++) { if(i==s||i==g) add_edge(i,i+n,2); else add_edge(i,i+n,1); } int ans=Dinic(s,g+n); if(ans == 2) puts("2"); if(ans == 0) printf("%d\n",n); if(ans == 1) { int cnt=0; int src=s; es[head[s]].w = es[head[g]].w=0; memset(vis,0,sizeof(vis)); while(true) { top=0; bfs(src); bool flag=0; for(int i =0 ; i < top; i++) { int u=que[i]; if(flag) break; for(int i = head[u];~i;i = es[i].nxt) { if(i&1) continue; int v=es[i].v,w=es[i].w; if(w == 0 && vis[v] == 0) { cnt++; src = v; flag=1; break; } } } if(src==g+n) break; } printf("%d\n",cnt); } } }
相关文章推荐
- 移动Web中图片自适应的两种JavaScript解决方法
- Remove Duplicates from Sorted List II
- android studio 目录结构
- 笔记——【C和指针】
- 大型网站架构改进历程:存储的瓶颈
- 数据结构与算法分析 L5
- ofbiz中的ofbiz-component.xml和加载过程
- 云计算容器服务该何去何从
- 投影仪矫正
- 《构建之法》--阅读(第13章-第17章)
- 绑定自己Self
- 13、14、15、16、17
- Python中的base64、base32实例
- 将数据库某列改为自增长
- 认识.NET
- Java_增强for循环
- ]9.zookeeper原理解析-选举之QuorumPeerMain加载
- NDK编译X265库到ARM,遇到问题
- 替换字符串String中的元素和分割字符串为数组
- 《构建之法》13,14,15,16,17章读后感