这题是最小费用最大流的问题,给出边的关系和花费,然后给吃D和K,D是要运输的数据流。K表示每条边能运输的最大流量,这图的应该构造无向图,而且自己发现,凡是要无向图的网络流问题最好还是用邻接表来表示这样就可以解决重边和反向边问题,之前用邻接矩阵来表示一直错= =
我们还要抽象出一个源点0,然后0-1的花费为0,容量是D,然后上模板就好了
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<queue> #define inf 111111111111111111 using namespace std; const int N=5550; struct node3 { int u,v; long long w; }E[N]; struct node4 { int v,u; int next; int f; int cap; long long cost; }G[50000]; long long d[110]; int head[110]; int p[110]; bool vis[110]; int n,m; int D,K; int num; void init() { memset(head,-1,sizeof(head)); num=0; } void add(int u,int v,int w,long long c) { G[num].u=u; G[num].v=v; G[num].cap=w; G[num].cost=c; G[num].f=0; G[num].next=head[u]; head[u]=num++; int tt=u; u=v; v=tt; G[num].u=u; G[num].v=v; G[num].cap=0; G[num].cost=-c; G[num].f=0; G[num].next=head[u]; head[u]=num++; } void EK_() { queue<int>q; int F=0; long long c=0; for(;;) { for(int i=0;i<=n;i++) d[i]=(i==0?0:inf); memset(p,-1,sizeof(p)); memset(vis,false,sizeof(vis)); q.push(0); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=false; for(int k=head[u];k!=-1;k=G[k].next) { int v=G[k].v; if(G[k].cap>G[k].f&&d[v]>d[u]+G[k].cost) { d[v]=d[u]+G[k].cost; p[v]=k; if(!vis[v]) { vis[v]=true; q.push(v); } } } } if(d[n]==inf) break; int a=999999999; for(int u=p[n];u!=-1;u=p[G[u].u]) { a=min(a,G[u].cap-G[u].f); } for(int k=p[n];k!=-1;k=p[G[k].u]) { G[k].f+=a; G[k^1].f-=a; } F+=a; c+=a*d[n]; } if(F==D) cout<<c<<endl; else cout<<"Impossible.\n"; } int main() { while(scanf("%d %d",&n,&m)!=EOF) { init(); for(int i=1;i<=m;i++) cin>>E[i].u>>E[i].v>>E[i].w; cin>>D>>K; add(0,1,D,0); for(int i=1;i<=m;i++) { add(E[i].u,E[i].v,K,E[i].w); add(E[i].v,E[i].u,K,E[i].w); } EK_(); } return 0; }
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<queue> #define inf 111111111111111111 using namespace std; const int N=5550; struct node3 { int u,v; long long w; }E[N]; struct node4 { int v,u; int next; int f; int cap; long long cost; }G[50000]; long long d[110]; int head[110]; int p[110]; bool vis[110]; int n,m; int D,K; int num; void init() { memset(head,-1,sizeof(head)); num=0; } void add(int u,int v,int w,long long c) { G[num].u=u; G[num].v=v; G[num].cap=w; G[num].cost=c; G[num].f=0; G[num].next=head[u]; head[u]=num++; int tt=u; u=v; v=tt; G[num].u=u; G[num].v=v; G[num].cap=0; G[num].cost=-c; G[num].f=0; G[num].next=head[u]; head[u]=num++; } void EK_() { queue<int>q; int F=0; long long c=0; for(;;) { for(int i=0;i<=n;i++) d[i]=(i==0?0:inf); memset(p,-1,sizeof(p)); memset(vis,false,sizeof(vis)); q.push(0); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=false; for(int k=head[u];k!=-1;k=G[k].next) { int v=G[k].v; if(G[k].cap>G[k].f&&d[v]>d[u]+G[k].cost) { d[v]=d[u]+G[k].cost; p[v]=k; if(!vis[v]) { vis[v]=true; q.push(v); } } } } if(d[n]==inf) break; int a=999999999; for(int u=p[n];u!=-1;u=p[G[u].u]) { a=min(a,G[u].cap-G[u].f); } for(int k=p[n];k!=-1;k=p[G[k].u]) { G[k].f+=a; G[k^1].f-=a; } F+=a; c+=a*d[n]; } if(F==D) cout<<c<<endl; else cout<<"Impossible.\n"; } int main() { while(scanf("%d %d",&n,&m)!=EOF) { init(); for(int i=1;i<=m;i++) cin>>E[i].u>>E[i].v>>E[i].w; cin>>D>>K; add(0,1,D,0); for(int i=1;i<=m;i++) { add(E[i].u,E[i].v,K,E[i].w); add(E[i].v,E[i].u,K,E[i].w); } EK_(); } return 0; }
时间: 2024-11-12 16:18:11