poj 1459 Power Network
A的第一道网络流,嘿嘿,相比较来说蛮合适的。题目不难,套模板,注意加超级源、超级汇。难就难在能把题看完,题目很纠结啊。。
题目大意就是说,输电网络中:p是发电站,c是用户。由Sample Input:输入边、p、c ,求最大流。
多源多汇!?加个源点连接所有p,所有c 连接汇点,又是单源单汇了。
ek
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define N 1000 6 #define M 10000 7 #define Inf 9999999 8 9 int G[N][N],c[N][N],f[N][N]; 10 int pre[N],que[M],n,vis[N]; 11 12 int ek(int s,int t) 13 { 14 int i,j,k,head,tail,flow=0; 15 memset(f,0,sizeof(f)); 16 while(1) 17 { 18 head=tail=0; 19 memset(vis,0,sizeof(vis)); 20 que[tail++]=s; 21 vis[s]=1; 22 while(head<tail) 23 { 24 k=que[head++]; 25 if(k==t)break; 26 for(i=0;i<=n+1;i++) 27 { 28 if(c[k][i]>0&&!vis[i]) 29 { 30 vis[i]=1; 31 pre[i]=k; 32 que[tail++]=i; 33 } 34 } 35 } 36 if(k!=t)break; 37 int cc=Inf; 38 j=t; 39 i=pre[j]; 40 while(j!=s) 41 { 42 if(c[i][j]<cc) 43 cc=c[i][j]; 44 j=i; 45 i=pre[j]; 46 } 47 flow+=cc; 48 j=t; 49 i=pre[j]; 50 while(j!=s) 51 { 52 f[i][j]+=cc; 53 f[j][i]=-f[i][j]; 54 c[i][j]=G[i][j]-f[i][j]; 55 c[j][i]=G[j][i]-f[j][i]; 56 j=i; 57 i=pre[j]; 58 } 59 } 60 return flow; 61 } 62 63 int main() 64 { 65 int np,nc,m,i; 66 int u,v,w; 67 char temp[15]; 68 while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) 69 { 70 memset(G,0,sizeof(G)); 71 memset(c,0,sizeof(c)); 72 for(i=0;i<m;i++) 73 { 74 scanf("%s",temp); 75 sscanf(temp,"(%d,%d)%d",&u,&v,&w); 76 G[u+1][v+1]=w; 77 c[u+1][v+1]=w; 78 } 79 80 for(i=0;i<np;i++) //超级源 81 { 82 scanf("%s",temp); 83 sscanf(temp,"(%d)%d",&v,&w); 84 G[0][v+1]=w; 85 c[0][v+1]=w; 86 } 87 88 for(i=0;i<nc;i++) //超级汇 89 { 90 scanf("%s",temp); 91 sscanf(temp,"(%d)%d",&u,&w); 92 G[u+1][n+1]=w; 93 c[u+1][n+1]=w; 94 } 95 printf("%d\n",ek(0,n+1)); 96 } 97 return 0; 98 } 99 /* 100 2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20 101 7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7 (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5 (0)5 (1)2 (3)2 (4)1 (5)4 102 */
dinic
1 #include<stdio.h> 2 #include<string.h> 3 4 #define MIN(a,b) a > b ? b : a 5 #define NUM 250 6 #define INF 0x7ffffff 7 8 typedef struct { 9 int e,f,next; 10 }info; 11 info edge[NUM * NUM]; 12 13 int head[NUM]; 14 int Que[NUM]; 15 int level[NUM]; 16 int n,nc,m,np; 17 int st,ed; 18 int tol; 19 20 void Add(int s,int t,int c) 21 { 22 edge[tol].e = t; //构建邻接表 23 edge[tol].f = c; 24 edge[tol].next = head[s]; 25 head[s] = tol ++; 26 27 edge[tol].e = s; //构建反向边 28 edge[tol].f = 0; 29 edge[tol].next = head[t]; 30 head[t] = tol ++; 31 } 32 33 int BFS() 34 { 35 int fr,tp,next,cur_level,cur; 36 memset(level,-1,sizeof(level)); 37 Que[0] = st; 38 level[st] = 0; 39 for( fr = 0,tp = 1; fr != tp; fr = (fr + 1)%NUM ){ 40 cur = Que[fr]; 41 cur_level = level[cur]; 42 for(next = head[cur]; next != -1; next = edge[next].next){ 43 if( edge[next].f && level[ edge[next].e ] == -1 ){ 44 Que[tp] = edge[next].e; 45 level[ edge[next].e ] = cur_level + 1; 46 tp = (tp + 1)%NUM; 47 } 48 } 49 } 50 return level[ed] != -1; 51 } 52 53 int DFS(int s,int min) 54 { 55 int r = 0,next; 56 int t; 57 if( s == ed ) return min; 58 for( next = head[s]; r < min && next != -1;next = edge[next].next ){ 59 if( edge[next].f && level[s] + 1 == level[ edge[next].e ] ){ 60 t = MIN( min - r,edge[next].f ); 61 t = DFS(edge[next].e,t); 62 r += t; 63 edge[next].f -= t; 64 edge[next^1].f += t; 65 } 66 } 67 if( !r )level[s] = -2; 68 return r; 69 } 70 71 int main() 72 { 73 int res,t; 74 int a,b,c; 75 while(~scanf("%d%d%d%d",&n,&np,&nc,&m)){ 76 st = n; //源点 77 ed = st + 1; //汇点 78 tol = 0; 79 memset(head,-1,sizeof(head)); 80 while(m --){ 81 scanf(" (%d,%d)%d",&a,&b,&c); 82 Add(a,b,c); 83 } 84 while(np --){ 85 scanf(" (%d)%d",&a,&c); 86 Add(st,a,c); 87 } 88 while(nc --){ 89 scanf(" (%d)%d",&a,&c); 90 Add(a,ed,c); 91 } 92 res = 0; 93 while( BFS() ){ 94 while( t = DFS(st,INF) ){ 95 res += t; 96 } 97 } 98 printf("%d\n",res); 99 } 100 return 0; 101 } 102 /* 103 2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20 104 7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7 (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5 (0)5 (1)2 (3)2 (4)1 (5)4 105 */
源自http://happylch21.blog.163.com/blog/static/16563975920116259323343/