LightOJ - 1404 Sending Secret Messages 費用流 EK演算法
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 N
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)
Now Alice wants to send P
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 next M 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
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
Sample Output
Case 1: 37
Case 2: 139
Case 3: impossible
題意:給定一個圖,有n個頂點m條無向邊,每條邊都有容量和費用,求從1到n穿輸p的資料量時的費用。題中流量和費用給反了
題解:費用流模板題 EK演算法介紹:點選檢視
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
const int N=52;
struct node{
int st,to,nex,cost,cap;
}e[N*N*2];
int head[N],dis[N],vis[N],pre[N],len;
int n,m,p;
void Init()
{
len=0;
memset(head,-1,sizeof(head));
}
void Add(int u,int v,int cost,int cap)
{
e[len].st=u;
e[len].to=v;
e[len].cost=cost;
e[len].cap=cap;
e[len].nex=head[u];
head[u]=len++;
e[len].st=v;
e[len].to=u;
e[len].cost=-cost;
e[len].cap=0;
e[len].nex=head[v];
head[v]=len++;
}
int cost_flow(int s,int t,int p)
{
int ans=0;
while(p>0)
{
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
queue<int> q;
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int now=q.front();q.pop();
vis[now]=0;
for(int i=head[now];i!=-1;i=e[i].nex)
{
int to=e[i].to;
if(e[i].cap>0&&dis[to]>dis[now]+e[i].cost)
{
dis[to]=dis[now]+e[i].cost;
pre[to]=i;
if(!vis[to])
q.push(to),vis[to]=1;
}
}
}
if(dis[t]==INF) return -1;
int minn=p;
for(int i=pre[t];i!=-1;i=pre[e[i].st])
minn=min(minn,e[i].cap);
for(int i=pre[t];i!=-1;i=pre[e[i].st])
e[i].cap-=minn,e[i^1].cap+=minn;
ans+=minn*dis[t];
p-=minn;
}
return ans;
}
int main()
{
int T,x,y,z,w,cas=1;
scanf("%d",&T);
while(T--)
{
Init();
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&z,&w);
Add(x,y,w,z);
Add(y,x,w,z);
}
int ans=cost_flow(1,n,p);
printf("Case %d: ",cas++);
if(ans!=-1) printf("%d\n",ans);
else printf("impossible\n");
}
return 0;
}