题目:http://acm.hdu.edu.cn/showproblem.php?pid=3987
题意:求边数最少的割集
思路:与上文一样
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1e18;
const int N = 500005;
int n,m,s,t,tot;
int head[N],dep[N],cur[N];
struct edge
{
int to,nxt;
ll cap;
edge(int t = 0,int n = 0,ll c = 0):to(t),nxt(n),cap(c){}
}E[N];
void init()
{
memset(head,-1,sizeof(head));
tot = 0;
}
void add(int u,int v,ll cap)
{
E[tot] = edge(v,head[u],cap);
head[u] = tot++;
}
bool bfs(int s,int t)
{
memset(dep,-1,sizeof(dep));
queue<int> q;
dep[s] = 0;
q.push(s);
while(!q.empty())
{
int u = q.front();q.pop();
for(int i = head[u];~i;i = E[i].nxt)
{
int v = E[i].to;
if(E[i].cap > 0 && dep[v] == -1)
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[t] != -1;
}
ll dfs(int u,ll flow)
{
if(u == t)
return flow;
ll w ,used = 0;
for(int i = head[u];~i;i = E[i].nxt)
{
int v = E[i].to;
if(dep[v] == dep[u]+1)
{
w = flow - used;
w = dfs(v,min(w,E[i].cap));
E[i].cap -= w;
E[i^1].cap += w;
if(v) cur[u] = i;
used += w;
if(used == flow) return flow;
}
}
if(!used) dep[u] = -1;
return used;
}
ll dinic(int s,int t)
{
ll res = 0;
while(bfs(s,t))
{
for(int i = 1;i <= t;i++)
cur[i] = head[i];
res += dfs(s,INF);
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
for(int ca = 1;ca <= T;ca++)
{
init();
scanf("%d%d",&n,&m);
s = 1,t = n;
int u,v,d;
ll w;
while(m--)
{
scanf("%d%d%lld%d",&u,&v,&w,&d);
++u;++v;
add(u,v,w*1000000+1);
if(d)
add(v,u,w*1000000+1);
else
add(v,u,0);
}
printf("Case %d: %lld\n",ca,dinic(s,t)%1000000);
}
return 0;
}