标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2301 Accepted Submission(s): 966
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<climits> 6 #define MAXP 110 7 #define MAXE 51000 8 using namespace std; 9 struct Edge 10 { 11 int s,t,f,c,next; 12 } edge[MAXE]; 13 int head[MAXP]; 14 int pre[MAXP]; 15 int dist[MAXP]; 16 bool isq[MAXP]; 17 int n,m,k,s,t,u,v,c,f,ent; 18 void add(int S,int T,int f,int c) 19 { 20 edge[ent].s=S; 21 edge[ent].t=T; 22 edge[ent].f=f; 23 edge[ent].c=c; 24 edge[ent].next=head[S]; 25 head[S]=ent++; 26 edge[ent].s=T; 27 edge[ent].t=S; 28 edge[ent].f=0; 29 edge[ent].c=-c; 30 edge[ent].next=head[T]; 31 head[T]=ent++; 32 } 33 int MIN(int a,int b) 34 { 35 return a<b?a:b; 36 } 37 bool spfa() 38 { 39 memset(pre,-1,sizeof(pre));//初始化路径为-1 40 for(int i=s; i<=t; i++) 41 { 42 isq[i]=false;//每点开始时均不在队列里面 43 dist[i]=INT_MAX;//初始化到每点的最小费用均为INT_MAX 44 } 45 queue<int>q; 46 q.push(s); 47 isq[s]=true;//源点s已经放入到队列里面去了 48 dist[s]=0;//从源点到源点的距离为0 49 while(!q.empty())//当队列为空时优化过程结束,退出循环 50 { 51 int temp1=q.front(); 52 q.pop(); 53 isq[temp1]=false;//该点已经退出队列 54 for(int i=head[temp1]; i!=-1; i=edge[i].next) //从该点找通过邻接表找所有的以该点为起点的边,从中找出能优化的点 55 { 56 int temp2=edge[i].t; 57 if(edge[i].f&&dist[temp2]>dist[temp1]+edge[i].c) 58 { 59 dist[temp2]=dist[temp1]+edge[i].c; 60 pre[temp2]=i; 61 if(!isq[temp2])//如果该点不在队列中,则将该点放入队列中 62 { 63 q.push(temp2); 64 isq[temp2]=true; 65 } 66 } 67 } 68 } 69 return pre[t]!=-1;//如果pre[t]==-1的话说明没有找到从s到t的路径,即已经找到所有的路径了,结束循环 70 } 71 void mcmf() 72 { 73 int tot=0; 74 int sum=0; 75 int mincost=INT_MAX; 76 int minn=INT_MAX; 77 while(spfa()) 78 { 79 tot++; 80 mincost=dist[t]; 81 sum+=mincost; 82 if(tot==k) 83 { 84 printf("%d\n",sum); 85 return; 86 } 87 for(int i=pre[t];i!=-1;i=pre[i])//最小费用最大流中的减流的过程 88 { 89 edge[i].f--; 90 edge[i^1].f++; 91 i=edge[i].s; 92 } 93 } 94 printf("-1\n"); 95 } 96 int main() 97 { 98 while(~scanf("%d%d%d",&n,&m,&k)) 99 { 100 ent=0; 101 memset(head,-1,sizeof(head)); 102 s=1;t=n; 103 for(int i=1;i<=m;i++) 104 { 105 scanf("%d%d%d%d",&u,&v,&c,&f); 106 for(int j=1;j<=f;j++) 107 add(u,v,1,(j*2-1)*c); 108 } 109 if(m==0||n==1) 110 { 111 printf("0\n"); 112 continue; 113 } 114 mcmf(); 115 } 116 return 0; 117 }
标签:
原文地址:http://www.cnblogs.com/lthb/p/4466953.html