1. 程式人生 > >poj1966Cable TV Network——無向圖最小割(最大流)

poj1966Cable TV Network——無向圖最小割(最大流)

一個 can struct div ret memcpy AI ostream ()

題目:http://poj.org/problem?id=1966

把一個點拆成入點和出點,之間連一條邊權為1的邊,跑最大流即最小割;

原始的邊權賦成inf防割;

枚舉源點和匯點,直接相鄰的兩個點不必枚舉;

註意:1、源點為枚舉點i的出點,匯點為枚舉點j的入點;

   2、讀入方式,免空格;

   3、在dinic跑最大流的過程中,會改變邊權,因此每次枚舉都要復制一組邊跑最大流,以免影響後面;

另:數據中的點從0開始,所以讀入的時候++來使用。

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include
<queue> using namespace std; queue<int>q; int n,m,head[105],cur[105],ct=1,inf=1e9,ans,d[105]; bool sid[55][55]; struct N{ int to,next,w; N(int t=0,int n=0,int ww=0):to(t),next(n),w(ww) {} }edge[6005],ed[6005]; void add(int x,int y,int z) { ed[++ct]=N(y,head[x],z);head[x]=ct; ed[++ct]=N(x,head[y],0
);head[y]=ct; } bool bfs(int s,int t) { memset(d,0,sizeof d); while(q.size())q.pop(); d[s]=1;q.push(s); while(q.size()) { int x=q.front();q.pop(); for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(!d[u]&&edge[i].w) { d[u]
=d[x]+1; q.push(u); } } } return d[t]; } int dfs(int x,int f,int t) { if(x==t)return f; int res=0; for(int i=cur[x];i;i=edge[i].next) { int u=edge[i].to; if(d[u]==d[x]+1&&edge[i].w) { int tmp=dfs(u,min(edge[i].w,f-res),t); edge[i].w-=tmp; edge[i^1].w+=tmp; res+=tmp; if(edge[i].w)cur[x]=i; if(res==f)return f; } } if(!res)d[x]=0; return res; } int dinic(int s,int t) { memcpy(edge,ed,sizeof ed);//!!! int res=0; while(bfs(s+n,t)) { for(int i=0;i<=2*n;i++)cur[i]=head[i]; res+=dfs(s+n,inf,t); } return res; } int main() { while(scanf("%d%d",&n,&m)==2) { if(!n||n==1) { printf("%d\n",n); continue; } if(!m) { printf("0\n"); continue; } ct=1;ans=inf; memset(head,0,sizeof head); memset(sid,0,sizeof sid); for(int i=1;i<=n;i++)add(i,i+n,1); // char dc=0; for(int i=1;i<=m;i++) { // dc=0; // while(dc!=‘(‘)scanf("%c",&dc); int x,y; scanf(" (%d,%d)",&x,&y);//或者采用註釋方法讀入,這裏為 scanf("%d,%d",&x,&y); x++;y++;// sid[x][y]=1;sid[y][x]=1; add(x+n,y,inf); add(y+n,x,inf); } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(!sid[i][j])ans=min(ans,dinic(i,j)); if(ans==inf)ans=n; printf("%d\n",ans); // dc=0; // while(dc!=‘)‘)scanf("%c",&dc); } return 0; }

poj1966Cable TV Network——無向圖最小割(最大流)