题目:
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 routers 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 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.
输出:
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.
样例输入:
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,汇点为给出的要输入的N。给出费用和容量,问从源点到汇点运送PkB花费最小费用是多少,如果不能运送完Pkb,则输出impossible。注意无向图要建两次边。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=60000;
const int INF=0x3f3f3f3f;
int head[maxn],dis[maxn],pre[maxn],vis[maxn];//dis是到这个点需要的费用,pre是当前点的前一个点
int cnt;
struct edge
{
int u,v,cap,cost,next;
}node[maxn<<1];
void add(int u,int v,int cost,int cap)
{
node[cnt].u=u;
node[cnt].v=v;
node[cnt].cost=cost;
node[cnt].cap=cap;
node[cnt].next=head[u];
head[u]=cnt++;
node[cnt].u=v;
node[cnt].v=u;
node[cnt].cost=-cost;
node[cnt].cap=0;
node[cnt].next=head[v];
head[v]=cnt++;
}
int maxflow(int s,int t,int p)
{
int res=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 u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=node[i].next)
{
edge e=node[i];
if(e.cap>0&&dis[e.v]>dis[e.u]+e.cost)
{
dis[e.v]=dis[e.u]+e.cost;
pre[e.v]=i;
if(!vis[e.v])
{
q.push(e.v);
vis[e.v]=1;
}
}
}
vis[u]=0;
}
if(dis[t]==INF)return -1;//如果到达不了汇点,则返回-1;
int d=p;
for(int i=pre[t];i!=-1;i=pre[node[i].u])
d=min(d,node[i].cap);//找到这条路径上最短的那一块
p-=d;
res+=d*dis[t];//走这条路径需要的花费
for(int i=pre[t];i!=-1;i=pre[node[i].u])
{
node[i].cap-=d;
node[i^1].cap+=d;
}
}
return res;
}
int main()
{
int t,N,M,P;
scanf("%d",&t);
int cas=0;
while(t--)
{
memset(head,-1,sizeof(head));
cnt=0;
scanf("%d%d%d",&N,&M,&P);
for(int i=1;i<=M;i++)
{
int u,v,w,c;
scanf("%d%d%d%d",&u,&v,&w,&c);
add(u,v,c,w);
add(v,u,c,w);
}
int res=maxflow(1,N,P);
if(res==-1)//如果没有到达汇点,就是到t的费用是INF,然后返回到这里-1
printf("Case %d: impossible\n",++cas);
else
printf("Case %d: %d\n",++cas,res);
}
return 0;
}