全裸的费用流,用来试模版的。
费用流:
在有代价与容量约束的网络上,安排一定的流量,使得所安排流量的费用或者代价达到最小,就是所谓的最小费用流问题。
如果所安排的流量为网络的最大流,则称为最小费用最大流。
求解最小费用流有两种经典算法,这里介绍一种增广路法。
主要思想是,从流量为零开始,不断选择增广路,增加流量,直到流量达到指定值为止
| Time Limit: 4 second(s) | Memory Limit: 32 MB |
Alice wants to send Bob some confidential messages. But their internet connection is not secured enough. As their names have been used in many networking schemes, they are very rich now. So, they don't want to send encoded messages, they want to use secured dedicated connection for them. So, they talked to some ISPS (Internet Service Providers) about their problem. Only they get is that there are Nrouters in the network, some of them share bidirectional links. Each link has a capacity, and for each KB of data passing through this link, they have to pay some money. Assume that Alice is connected with the 1st router and Bob is connected to the Nth router.
For example, in the picture, Alice wants to send 4 KB data from router 1 to router 6. Each link is identified by two integers in the form (a, b) where 'a' denotes the capacity of the link and 'b' denotes per KB cost of the link. So, Alice can send 1KB of data through 1 - 2 - 3 - 4 - 6 (cost 8), 2KB data through 1 - 5 - 6 (cost 2 * 9=18) and 1KB data through 1 - 3 - 4 - 6 (cost 11). So, the total cost is 37 units.
Now Alice wants to send P KB of data to Bob. You have to find the minimum amount of money they have to pay to achieve their goal.
Input
Input starts with an integer T (≤ 50), denoting the number of test cases.
Each case starts with a blank line. Next line contains three integers N (2 ≤ N ≤ 50), M (0 ≤ M ≤ N*(N-1)/2) and P (1 ≤ P ≤ 1000), where M denotes the number of bidirectional links. Each of the nextM lines contains four integers u v w c (1 ≤ u, v ≤ N, u ≠ v, 1 ≤ w, c ≤ 100), meaning that there is a link between router u and v, and at most c KB data can be sent through this link, and each KB of data through this link will cost w. You can assume that there will be at most one connection between a pair of routers.
Output
For each case, print the case number and the minimum amount of money required or "impossible" if it's not possible to send P KB of data.
Sample Input |
Output for Sample Input |
|
3
6 9 4 3 1 9 8 1 2 1 2 1 5 6 1 5 6 2 8 6 4 2 2 4 2 7 6 2 6 7 9 3 4 5 1 3 2 2 3
6 9 9 3 1 9 8 1 2 1 2 1 5 6 1 5 6 2 8 6 4 2 2 4 2 7 6 2 6 7 9 3 4 5 1 3 2 2 3
4 4 20 1 3 1 3 3 4 1 4 1 2 1 2 2 4 1 5 |
Case 1: 37 Case 2: 139 Case 3: impossible
|
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 8 #define N 55 9 #define E 100000 10 #define LL int 11 #define inf 1<<29 12 LL ans,anscost; 13 struct edge{ 14 int u,v; 15 LL cap,flow,cost; 16 int next; 17 }et[E]; 18 int S,T,tot; 19 int eh[N]; 20 void add(int u,int v,LL c,LL f,LL cost){ 21 edge e={u,v,c,f,cost,eh[u]}; 22 et[tot]=e; 23 eh[u]=tot++; 24 } 25 void addedge(int u,int v,LL c,LL cost){ 26 add(u,v,c,0,cost),add(v,u,0,0,0); 27 } 28 29 int p[N]; 30 LL low[N],dis[N]; 31 bool vit[N]; 32 bool spfa(){ 33 queue<int>q; 34 memset(vit,0,sizeof(vit)); 35 memset(p,-1,sizeof(p)); 36 fill(dis,dis+N,inf); 37 vit[S]=1; 38 dis[S]=0; 39 low[S]=inf; 40 q.push(S); 41 while(!q.empty()){ 42 int u=q.front(); 43 q.pop(); 44 vit[u]=0; 45 int i; 46 for(i=eh[u];i!=-1;i=et[i].next){ 47 int v=et[i].v; 48 LL cap=et[i].cap,flow=et[i].flow,cost=et[i].cost; 49 if(cap-flow>0&&dis[u]+cost<dis[v]){ 50 dis[v]=dis[u]+cost; 51 p[v]=i; 52 low[v]=low[u] < (cap-flow) ? low[u]:(cap-flow); 53 if(!vit[v]){ 54 vit[v]=1; 55 q.push(v); 56 } 57 } 58 } 59 } 60 return dis[T]!=inf; 61 } 62 void costflow(){ //S为起点,T为终点,ans为最大流,anscost为最小费用 63 ans=0;anscost=0; 64 while(spfa()){ 65 int x=p[T]; 66 ans+=low[T]; 67 anscost+=low[T]*dis[T]; 68 while(x!=-1){ 69 et[x].flow+=low[T]; 70 et[x^1].flow-=low[T]; 71 et[x^1].cost=-et[x].cost; 72 x=p[et[x].u]; 73 } 74 } 75 } 76 void init(){ 77 tot=0; 78 memset(eh,-1,sizeof(eh)); 79 } 80 int main(){ 81 int t,cas=1; 82 cin>>t; 83 while(t--){ 84 init(); 85 int n,m,p; 86 cin>>n>>m>>p; 87 S=1,T=n+1; 88 while(m--){ 89 int u,v,w,c; 90 scanf("%d%d%d%d",&u,&v,&w,&c); 91 addedge(u,v,w,c); 92 addedge(v,u,w,c); 93 } 94 addedge(n,n+1,p,0); 95 costflow(); 96 printf("Case %d: ",cas++); 97 if(ans==p) printf("%d\n",anscost); 98 else puts("impossible"); 99 } 100 return 0; 101 }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 8 #define N 55 9 #define E 100000 10 #define LL int 11 #define inf 1<<29 12 LL ans,anscost; 13 struct edge{ 14 int u,v; 15 LL cap,flow,cost; 16 int next; 17 }et[E]; 18 int S,T,tot; 19 int eh[N]; 20 void add(int u,int v,LL c,LL f,LL cost){ 21 edge e={u,v,c,f,cost,eh[u]}; 22 et[tot]=e; 23 eh[u]=tot++; 24 } 25 void addedge(int u,int v,LL c,LL cost){ 26 add(u,v,c,0,cost),add(v,u,0,0,0); 27 } 28 29 int p[N]; 30 LL low[N],dis[N]; 31 bool vit[N]; 32 bool spfa(){ 33 queue<int>q; 34 memset(vit,0,sizeof(vit)); 35 memset(p,-1,sizeof(p)); 36 fill(dis,dis+N,inf); 37 vit[S]=1; 38 dis[S]=0; 39 low[S]=inf; 40 q.push(S); 41 while(!q.empty()){ 42 int u=q.front(); 43 q.pop(); 44 vit[u]=0; 45 int i; 46 for(i=eh[u];i!=-1;i=et[i].next){ 47 int v=et[i].v; 48 LL cap=et[i].cap,flow=et[i].flow,cost=et[i].cost; 49 if(cap-flow>0&&dis[u]+cost<dis[v]){ 50 dis[v]=dis[u]+cost; 51 p[v]=i; 52 low[v]=low[u] < (cap-flow) ? low[u]:(cap-flow); 53 if(!vit[v]){ 54 vit[v]=1; 55 q.push(v); 56 } 57 } 58 } 59 } 60 return dis[T]!=inf; 61 } 62 void costflow(){ //S为起点,T为终点,ans为最大流,anscost为最小费用 63 ans=0;anscost=0; 64 while(spfa()){ 65 int x=p[T]; 66 ans+=low[T]; 67 anscost+=low[T]*dis[T]; 68 while(x!=-1){ 69 et[x].flow+=low[T]; 70 et[x^1].flow-=low[T]; 71 et[x^1].cost=-et[x].cost; 72 x=p[et[x].u]; 73 } 74 } 75 } 76 void init(){ 77 tot=0; 78 memset(eh,-1,sizeof(eh)); 79 } 80 int main(){ 81 int t,cas=1; 82 cin>>t; 83 while(t--){ 84 init(); 85 int n,m,p; 86 cin>>n>>m>>p; 87 S=1,T=n+1; 88 while(m--){ 89 int u,v,w,c; 90 scanf("%d%d%d%d",&u,&v,&w,&c); 91 addedge(u,v,w,c); 92 addedge(v,u,w,c); 93 } 94 addedge(n,n+1,p,0); 95 costflow(); 96 printf("Case %d: ",cas++); 97 if(ans==p) printf("%d\n",anscost); 98 else puts("impossible"); 99 } 100 return 0; 101 }
浙公网安备 33010602011771号