UVA 1660 Cable TV Network [最小割] [图的连通度] [拆点]
来源:互联网 发布:平移旋转变换矩阵 编辑:程序博客网 时间:2024/04/29 11:48
Cable TV Network
Time Limit: 3000MS 64bit IO Format: %lld & %llu
求无向图的点连通度,也就是说求任意两点最小割的最小值。
但是考虑S集合和T集合,中间由若干条边连接,这些边就是S到T的最小割,假设这种情况是答案,那么发现其实不需要枚举所有的点,而是固定一个点,枚举另一个点就可以保证有至少一种情况是一点在S集合另一点在T集合里。
然后由于一个点只能经过一次,那么拆点之后连接容量为1的边,然后其他边连成INF。
注意每次都要把源点和汇点容量生成INF,表示不能切这条边。
论文中还提到另外的方法,可以求出原图的最小生成树再来求解,对于这道题来说没有必要。
下面是枚举所有点对的代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>using namespace std;inline int read(int &x){ x=0; char ch='\0';int flag=1; while(ch<'0'||ch>'9') { ch=getchar(); if(ch==EOF) return -1; if(ch=='-') { flag=-1;ch=getchar();break; } } while(ch>='0'&&ch<='9') { x*=10; x+=ch-'0'; ch=getchar(); } x*=flag; return 1;}const int INF=0x3f3f3f3f;const int maxn=50+5;struct Edge{ int to,next; int cap;}edge0[maxn*maxn<<2],edge[maxn*maxn<<2];int head[maxn<<1];int maxedge0;inline void addedge(int u,int v,int cap){ edge0[++maxedge0]=(Edge){v,head[u],cap}; head[u]=maxedge0; edge0[++maxedge0]=(Edge){u,head[v],0}; head[v]=maxedge0;}int n,m;bool Zero;inline bool init(){ if(!~read(n)||!~read(m)) return false; if((n==0||n==1)&&m==0) { printf("%d\n",n);Zero=true;return true; } memset(head,-1,sizeof(head)); maxedge0=-1; for(int i=1;i<=n;i++) addedge(i,i+n,1); for(int i=1;i<=m;i++) { int a,b; read(a),read(b); a++,b++; addedge(a+n,b,INF); addedge(b+n,a,INF); } return true;}int d[maxn<<1],cur[maxn<<1];bool vis[maxn<<1];inline bool bfs(int S,int T){ queue <int> que; memset(vis,false,sizeof(vis)); vis[S]=true;d[S]=1;que.push(S); while(!que.empty()) { int u=que.front();que.pop(); for(int i=head[u];~i;i=edge[i].next) { if(!edge[i].cap) continue;//both cap>0 and non_visited!!! int v=edge[i].to; if(vis[v]) continue; d[v]=d[u]+1; if(v==T) return true; que.push(v),vis[v]=true; } } return false;}int dfs(int u,int T,int minflow){ if(u==T||minflow==0) return minflow; int flow=0; for(int &i=cur[u];~i;i=edge[i].next) { int v=edge[i].to,f; if(d[v]==d[u]+1&&(f=dfs(v,T,min(minflow,edge[i].cap)))) { edge[i].cap-=f; edge[i^1].cap+=f; flow+=f; minflow-=f; if(!minflow) return flow; } } return flow;}inline int dinic(int S,int T){ int ret=0; while(bfs(S,T)) { memcpy(cur,head,sizeof(head)); ret+=dfs(S,T,INF); } return ret;}inline void edgecpy(){ for(int k=0;k<=maxedge0;k++) edge[k]=edge0[k];}inline void expand(int x){ edge[(x<<1)-2].cap=INF;}inline int work(){ int ret=n; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { edgecpy(); expand(i);expand(j); int tmp=dinic(i,j+n);//from the inside vertex if(ret>tmp) ret=tmp; } return ret;}int main(){ freopen("tv.in","r",stdin); freopen("tv.out","w",stdout); while(init()) { if(Zero) { Zero=false;continue; } printf("%d\n",work()); } return 0;}
0 0
- UVA 1660 Cable TV Network [最小割] [图的连通度] [拆点]
- 点连通度 边连通度 最大流最小割 最小割点集 最小割边集 & POJ 1966 Cable TV Network
- 【连通图|点连通度】POJ-1966 Cable TV Network
- POJ1966 Cable TV Network 点连通度
- POJ 1966 - Cable TV Network 暴力枚举+最小点割
- pku 1966 Cable TV Network(求无向图的点连通度)
- POJ 1966 Cable TV Network 无向图的点连通度
- POJ1966.Cable TV Network——无向图的点连通度
- Cable TV Network-POJ1966图的连通度
- poj--1966[Cable TV Network] 拆点+枚举源汇求最小割
- Cable TV Network, ACM/ICPC SEERC 2004, UVa1660【Dinic 最小割 拆点】
- 1660 - Cable TV Network(最大流最小割)
- vua 1660 Cable TV Network 最大流最小割 求割点
- poj 1966 Cable TV Network 无向图最小割
- POJ 1966 Cable TV Network 最小割
- poj 1966 Cable TV Network 点连通度
- POJ 1966--Cable TV Network 【求无向图的点连通度 构造最大流模型 && dinic】
- 【poj1966】Cable TV Network 无向图点连通度(最大流)
- EditView属性大全
- 三级菜单:有滚动跳转和选择展示相应内容
- centos客户机连接错误,SQL30081N 检测到通信错误
- HDU1155Bungee Jumping(物理+数学)
- HDU 1563 Find your present!
- UVA 1660 Cable TV Network [最小割] [图的连通度] [拆点]
- 总结
- HDU1869:六度分离(Floyd)
- Http2.0协议 开源库调研结果
- Android基于surfaceview与mediaplayer的视频播放器(android-studio)
- 个人对win7开机黑屏只有鼠标排障总结
- HDU 1702 ACboy needs your help again!
- 写一个方法,参数接收一个String类型的对象,最终可以把这个字符串参数中出现过的每一个字母打印出来 例如: "wwqweqdasdafdsfdsferer" 将来方法接收这个参数后会打印:
- iOS 技术博客