UPD:原來是因爲參數傳遞是用棧控制的 按照如下方式傳參會變成 就……可以防hack?
快讀玄學錯誤浪費我一個晚上+早上
發現如果不直接在addedge()函數裏用read做參數 比如
而是先聲明u,v,c,d 用read()讀入的值存在裏面
然後
就……就tmA了
而且按照第一種寫法 在ins函數裏輸出c 結果會輸出v的值……所有邊都是這樣 直接導致wa……
題解:
如果題目最大邊數是E(雙向邊就2E)
割斷每條邊的代價就是邊的容量 求代價最小時割的最小邊數
我們可以在插邊的時候 把邊的容量設成 其中是邊原來的容量
這樣的話 dinic()算出來的最小割結果記爲ans 原題求解的最小代價即爲
因爲所有弧的流量乘的那個都被除掉了 剩下的所有多加的1的和是小於的
同理 求的最小代價下的最小割邊數 可以用表示 因爲所有多加的1代表了邊數 多乘的(E+1)被模掉不影響結果
求代價最小的最小割邊數代碼如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
int n, m;
const int maxn = 1007;
const ll E = 200001;
const ll inf = 100000000000;
struct edge {
int v, next;
ll c;
}e[E << 1];
int p[maxn], eid = 0, d[maxn];
int S, T;
void init() {
memset(p, -1, sizeof(p));
eid = 0;
}
void ins(int u, int v, ll c) {
e[eid].c = c*E+1; e[eid].v = v; e[eid].next = p[u]; p[u] = eid++;
e[eid].c = 0; e[eid].v = u; e[eid].next = p[v]; p[v] = eid++;
}
void addedge(int u, int v, ll c, int d) {
if (d == 1) {
ins(u, v, c);
ins(v, u, c);
}
else {
ins(u, v, c);
}
}
bool bfs() {
memset(d, -1, sizeof(d));
int v;
queue<int> q;
q.push(S);
d[S] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = p[u]; ~i; i = e[i].next) {
v = e[i].v;
//printf("%lld\n", e[i].c);
if (e[i].c && d[v] == -1) {
d[v] = d[u] + 1;
q.push(v);
if (v == T) return true;
}
}
}
return false;
}
ll dfs(int u, ll flow) {
if (u == T) return flow;
ll res = 0;
int v;
for (int i = p[u]; ~i; i = e[i].next) {
v = e[i].v;
//printf("%d %lld\n", v, e[i].c);
if (e[i].c && d[v] == d[u] + 1){
ll tmp = dfs(v, min(flow, e[i].c));
//printf("%lld\n", tmp);
res += tmp;
flow -= tmp;
e[i].c -= tmp;
e[i ^ 1].c += tmp;
if (flow == 0) break;
}
}
if (res == 0) d[u] = -1;
//printf("%lld\n", res);
return res;
}
ll dinic() {
ll res = 0;
while (bfs()) res += dfs(S, inf);
return res;
}
inline int read() {
int s = 0, f = 1; char c = getchar(); while (c<'0' || c>'9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0'&&c <= '9') { s = s * 10 + c - '0'; c = getchar(); }
return s*f;
}
int main() {
n = read();
m = read();
S = 0;
T = n - 1;
init();
int u, v, c, d;
while (m--) {
u = read(); v = read(); c = read(); d = read();
addedge(u,v,c,d);
}
cout << dinic() % E;
//getchar();
return 0;
}