BZOJ 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 最小割_网络流
Code:
#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 1000000
#define inf 10000000
using namespace std;
namespace Dinic{
int S,T;
struct Edge{
int from,to,cap;
Edge(int u,int v,int c):from(u),to(v),cap(c){}
};
vector<int>G[maxn];
vector<Edge>edges;
queue<int>Q;
void addedge(int u,int v,int c){
edges.push_back(Edge(u,v,c));
edges.push_back(Edge(v,u,0));
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
int d[maxn],vis[maxn];
int current[maxn];
int BFS(){
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
d[S] = 0,vis[S] = 1; Q.push(S);
while(!Q.empty()){
int u=Q.front(); Q.pop();
int m=G[u].size();
for(int i=0;i<m;++i) {
Edge r = edges[G[u][i]];
if(!vis[r.to] && r.cap > 0) {
d[r.to] = d[u] + 1;
vis[r.to] = 1;
Q.push(r.to);
}
}
}
return vis[T];
}
int dfs(int x,int cur){
if(x == T) return cur;
int flow=0,f;
int m=G[x].size();
for(int i=current[x];i<m;++i) {
current[x] = i;
int u=G[x][i];
Edge r = edges[u];
if(d[r.to] == d[x] + 1 && r.cap >0) {
f = dfs(r.to,min(cur,r.cap));
if(f > 0) {
flow += f,cur -= f;
edges[u].cap -= f,edges[u ^ 1].cap += f;
}
}
if(cur == 0) break;
}
return flow;
}
int maxflow(){
int flow = 0;
while(BFS())
{
memset(current,0,sizeof(current));
flow += dfs(S,inf);
}
return flow;
}
};
int vis[maxn];
#define row1(i) (i)
#define row2(i) (i + n)
int main()
{
// setIO("input");
int n,m,k,s,t;
scanf("%d%d%d",&n,&m,&k);
for(int i=1,u,v;i<=m;++i)
{
scanf("%d%d",&u,&v);
Dinic::addedge(row2(u), row1(v), inf);
Dinic::addedge(row2(v), row1(u), inf);
}
s=row2(n+3),t = 1;
Dinic::S=s;
Dinic::T=t;
for(int i=1,a;i<=k;++i)
{
scanf("%d",&a), vis[a]=1;
Dinic::addedge(s, row1(a), inf);
}
for(int i=1;i<=n;++i)
{
if(vis[i])
{
Dinic::addedge(row1(i), row2(i), inf);
}
else
{
Dinic::addedge(row1(i), row2(i), 1);
}
}
printf("%d\n",Dinic::maxflow());
}