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()); 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/10978520.html