题意:给出一张图,然后给出K和D,D表示每条路的容量,然后由点1到点n运送数据,流量为K时的最小费用。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <climits>
using namespace std;
typedef long long ll;
const ll INF=1e+18;
const int maxn=100+10;
const int maxm=5000+10;
struct Edge
{
int from,to;
ll cap,flow,cost;
Edge(int from,int to,ll cap,ll flow,ll cost):from(from),to(to),cap(cap),flow(flow),cost(cost){}
};
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
ll d[maxn];
int p[maxn];
ll a[maxn];
int u[maxm],v[maxm];
ll D,K,times[maxm];
void init()
{
for(int i=0;i<=n;i++)G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,ll cap,ll cost)
{
edges.push_back(Edge(from,to,cap,0,cost));
edges.push_back(Edge(to,from,0,0,-cost));
int x=edges.size();
G[from].push_back(x-2);
G[to].push_back(x-1);
}
bool Bellman_Ford(int s,int t,ll &flow,ll &cost)
{
for(int i=0;i<=n;i++)d[i]=INF;
d[s]=0;
inq[s]=1;
p[s]=0;
a[s]=INF;
queue<int> q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
inq[u]=0;
for(int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
if(e.cap>e.flow && d[e.to]>d[u]+e.cost)
{
d[e.to]=d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]=min(a[u],e.cap-e.flow);
if(!inq[e.to]){q.push(e.to);inq[e.to]=1;}
}
}
}
if(d[t]==INF)return false;
flow+=a[t];
cost+=d[t]*a[t];
int u=t;
while(u!=s)
{
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
u=edges[p[u]].from;
}
return true;
}
ll Mincost(int s,int t,ll &flow,ll &cost)
{
flow=0,cost=0;
while(Bellman_Ford(s,t,flow,cost));
return cost;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%lld",&u[i],&v[i],×[i]);
}
scanf("%lld%lld",&D,&K);
AddEdge(0,1,D,0);
for(int i=0;i<m;i++)
{
AddEdge(u[i],v[i],K,times[i]);
AddEdge(v[i],u[i],K,times[i]);
}
ll flow,cost;
Mincost(0,n,flow,cost);
if(flow<D)printf("Impossible.\n");
else printf("%lld\n",cost);
}
return 0;
}