题目大意:
在无向图G中把D单位的数据从1号点传到N号点,每条边允许传输数据的最大容量均为K,给出每条边传输单位数据的费用,求最小传输D单位数据的费用。
解析:
注意是无向图,必然要用邻接表,将无向边分成两个方向的有向边。1为源点,N为汇点,求流量为D的最小费用,因为费用为D,则用0到1的容量为D,表示初始的费用。
在无向图G中把D单位的数据从1号点传到N号点,每条边允许传输数据的最大容量均为K,给出每条边传输单位数据的费用,求最小传输D单位数据的费用。
解析:
注意是无向图,必然要用邻接表,将无向边分成两个方向的有向边。1为源点,N为汇点,求流量为D的最小费用,因为费用为D,则用0到1的容量为D,表示初始的费用。
然后套模板,求出0~n的最小费用。
总结:照着模板敲代码,我都能敲错,看来我真的是太粗心了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 105;
struct Edge {
int from,to,cap,flow,cost;
Edge(int u,int v,int c,int f,ll w) {
from = u;
to = v;
cap = c;
flow = f;
cost = w;
}
};
struct MCMF {
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
void init(int n) {
this->n = n;
for(int i = 0; i < n; i++) {
G[i].clear();
}
edges.clear();
}
void addEdge(int from,int to,int cap,ll cost) {
edges.push_back(Edge(from,to,cap,0,cost));
edges.push_back(Edge(to,from,0,0,-cost));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BellmanFord(int s,int t,int &flow,ll &cost) {
memset(d,0,sizeof(d));
for(int i = 0; i < n; i++) {
d[i] = INF;
}
memset(inq,0,sizeof(inq));
d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF;
queue<int> que;
que.push(s);
while(!que.empty()) {
int u = que.front();
que.pop();
inq[u] = false;
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]) {
que.push(e.to);
inq[e.to] = true;
}
}
}
}
if(d[t] == INF) {
return false;
}
flow += a[t];
cost += (ll)d[t] * (ll)a[t];
for(int u = t; u != s; u = edges[p[u]].from) {
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
}
return true;
}
int MincostMaxflow(int s,int t,ll& cost) {
int flow = 0;
cost = 0;
while(BellmanFord(s,t,flow,cost));
return flow;
}
};
struct Node {
int u,v,w;
}e[5005];
int main() {
int n,m;
ll D,K;
MCMF mcmf;
while(scanf("%d%d",&n,&m) != EOF) {
mcmf.init(n+1);
for(int i = 0; i < m; i++) {
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
}
scanf("%lld%lld",&D,&K);
mcmf.addEdge(0,1,D,0);
for(int i = 0; i < m; i++) {
mcmf.addEdge(e[i].u,e[i].v,K,e[i].w);
mcmf.addEdge(e[i].v,e[i].u,K,e[i].w);
}
int ans = mcmf.MincostMaxflow(0,n,K);
if(ans == D) {
printf("%lld\n",K);
}else {
printf("Impossible.\n");
}
}
return 0;
}