https://www.luogu.com.cn/problem/UVA10594
题目大意:题面太长就不放了,其实就是给定了一张无向图,每条边的流量是一个定值,同时有一个权值,问总共
D
D
D个数据能否从顶点
1
1
1传输到顶点
n
n
n,若能则输出花费的最小时间,否则输出
I
m
p
o
s
s
i
b
l
e
.
Impossible.
Impossible.
思路:很明显的费用流,建图也很简单,把顶点 0 0 0当作源点,给 0 0 0到 1 1 1加一条流量为 D D D、权值为 0 0 0的有向边,其它的边照常加,不过因为是无向图,所以要加两次。(不要把这个和自己加的反边搞混了)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=105;
const int maxm=1e4+5;
struct Edge
{
int to,nxt,dis,f;
}edge[maxm<<1];
int n,m,s,t,tot;
int head[maxn],vis[maxn],pre[maxn];
ll dis[maxn],maxf[maxn];
inline void addedge(int u,int v,int d)
{
edge[++tot].to=v,edge[tot].nxt=head[u],edge[tot].dis=d,head[u]=tot;
edge[++tot].to=u,edge[tot].nxt=head[v],edge[tot].dis=-d,edge[tot].f=0,head[v]=tot;
}
bool spfa()
{
for(int i=1;i<=n;i++)
dis[i]=INF;
dis[s]=0;
queue<int> q;
q.push(s),vis[s]=1,maxf[s]=INF;
while(!q.empty())
{
int u=q.front();
vis[u]=0;
q.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(edge[i].f&&dis[v]>dis[u]+edge[i].dis)
{
dis[v]=dis[u]+edge[i].dis;
pre[v]=i;
maxf[v]=min(maxf[u],(ll)edge[i].f);
if(!vis[v])
q.push(v),vis[v]=1;
}
}
}
return dis[t]!=INF;
}
void MCMF(ll &mflow,ll &mcost)
{
while(spfa())
{
int u=t,v;
while(u!=s)
{
v=pre[u];
edge[v].f-=maxf[t];
edge[v^1].f+=maxf[t];
u=edge[v^1].to;
}
mflow-=maxf[t];
mcost+=dis[t]*maxf[t];
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(head,0,sizeof(head));
tot=1;
s=0,t=n;
int u,v,w;
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
int d,k;
scanf("%d %d",&d,&k);
for(int i=2;i<=tot;i+=2)
edge[i].f=k;
addedge(s,1,0);
edge[tot-1].f=d;
ll mflow=d,mcost=0;
MCMF(mflow,mcost);
if(mflow)
printf("Impossible.\n");
else
printf("%lld\n",mcost);
}
return 0;
}