题意:网络中传送数据量为D的数据,每条边容量为K,需要花一定的时间。问传送完数据花费的最少时间。
思路:最小费用最大流。为了控制流量,除了输入描述的图外,加上一条边,即真正的源到输入的源,其容量为数据量。需要注意时间比较大,得用long long;图中的边是双向的,但是两个相反的方向不能认为互为逆向边,需要加入逆向的负权边,不过我实现的时候没加,用了当前流量判断时间应该是正还是负。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <ctype.h>
#define INF 10000000000000000ll
using namespace std;
int N,M;
long long cost[110][110];
long long c[110][110];
long long f[110][110];
int main(){
while(cin>>N>>M){
memset(cost,0,sizeof(cost));
memset(c,0,sizeof(c));
memset(f,0,sizeof(f));
int u,v,w;
for(int i=1;i<=M;i++){
cin>>u>>v>>w;
cost[u][v]=cost[v][u]=w;
c[u][v]=c[v][u]=1;
}
int D,K;
cin>>D>>K;
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
if(c[i][j])c[i][j]=K;
}
}
c[0][1]=c[1][0]=D;
bool inq[110];
int pre[110];
long long a[110];
long long b[110];
long long maxf=0;
long long minc=0;
while(true){
memset(a,0,sizeof(a));
a[0]=INF;
for(int i=1;i<=N;i++)b[i]=INF;
b[0]=0;
memset(inq,0,sizeof(inq));
queue<int> que;
que.push(0);
while(!que.empty()){
int cur=que.front();que.pop();inq[cur]=false;
for(int i=0;i<=N;i++){
if(f[cur][i]>=0){
if( (b[cur]+cost[cur][i]<b[i])&&(c[cur][i]-f[cur][i])>0 ){
if(!inq[i]){
inq[i]=true;
que.push(i);
}
long long t=min(a[cur],c[cur][i]-f[cur][i]);
pre[i]=cur;
b[i]=b[cur]+cost[cur][i];
a[i]=t;
}
}else{
if( (b[cur]-cost[cur][i]<b[i])&&(c[cur][i]-f[cur][i])>0 ){
if(!inq[i]){
inq[i]=true;
que.push(i);
}
long long t=min(a[cur],c[cur][i]-f[cur][i]);
pre[i]=cur;
b[i]=b[cur]-cost[cur][i];
a[i]=t;
}
}
}
}
if(!a[N])break;
maxf+=a[N];
minc+=b[N]*a[N];
for(int i=N;i!=0;i=pre[i]){
f[pre[i]][i]+=a[N];
f[i][pre[i]]-=a[N];
}
}
if(maxf==D){
cout<<minc<<endl;
}else{
cout<<"Impossible."<<endl;
}
}
return 0;
}