题目大意:有N个点,每个点的容量都是相同的,都为K,给出M个连接的点和这两个连接的点通信的代价,求将D个数据从点1送到点N的最小代价是多少
解题思路:每个点的容量可以将其看成是边的容量,然后设置一个超级源点0,超级源点0和点1相连,点0和点1之间的权值为D,这样图就建成了,注意两个点之间传输的代价是有可能大于10^15,所以要用long long
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 110
#define maxm 21000
#define ll long long
const ll INF = 1000000000000000000ll;
using namespace std;
int a[maxm],b[maxm],vis[maxn],u[maxm],v[maxm],head[maxm],next[maxm],line[maxm],pre[maxm];
int e,N,M;
ll t[maxm],flow[maxm],cost[maxm],d[maxm],D,K;
void add(int x,int y,ll c,ll f) {
u[e] = x;
v[e] = y;
cost[e] = c;
flow[e] = f;
next[e] = head[x];
head[x] = e;
e++;
}
void init() {
e = 0;
memset(head,-1,sizeof(head));
for(int i = 0; i < M; i++)
scanf("%d%d%lld",&a[i],&b[i],&t[i]);
scanf("%lld%lld",&D,&K);
for(int i = 0; i < M; i++) {
add(a[i],b[i],t[i],K);
add(b[i],a[i],-t[i],0);
add(b[i],a[i],t[i],K);
add(a[i],b[i],-t[i],0);
}
add(0,1,0,D);
add(1,0,0,0);
}
void spfa() {
int u;
memset(vis,0,sizeof(vis));
queue<int> q;
for(int i = 1; i <= N; i++)
d[i] = INF;
d[0] = 0;
q.push(0);
while(!q.empty()) {
u = q.front();
vis[u] = 0;
q.pop();
for(int i = head[u]; i != -1; i = next[i])
if(flow[i] && d[v[i]] > d[u] + cost[i]) {
d[v[i]] = d[u] + cost[i];
pre[v[i]] = u;
line[v[i]] = i;
if(!vis[v[i]]) {
vis[v[i]] = 1;
q.push(v[i]);
}
}
}
}
void EK() {
long long ans = 0, f = 0;
while(1) {
spfa();
if(d[N] == INF)
break;
ll MIN = INF;
int temp;
for(int i = N; i != 0; i = pre[i]) {
temp = line[i];
if(flow[temp] < MIN)
MIN = flow[temp];
}
for(int i = N; i != 0; i = pre[i]) {
int temp = line[i];
flow[temp] -= MIN;
flow[temp^1] += MIN;
}
ans += MIN * d[N];
f += MIN;
}
if(f == D)
printf("%lld\n",ans);
else
printf("Impossible.\n");
}
int main() {
while(scanf("%d%d",&N,&M) != EOF) {
init();
EK();
}
return 0;
}