• bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害【最小割】


    枚举建图.jpg
    一开始建的图挂了,于是枚举了几种建图方式……
    因为要删点,所以拆点,连接(i,i',1),对于原来图上的边(u,v),连接(u',v,inf),(v',u,inf),然后连接(s,i',inf),对于不能和1相连的点x,建边(x,t,inf)
    跑dinic即可
    原因的话,枚举出来就好啦 考虑1不能和x相连,把1和x分别连s和t,这样模型就转换为把st割开的最小割了
    比如下图这样,原图有一条1→i→x的通路而1,x不能互相连接,所以正好是把(i,i',1)这条边割掉,说明删掉i点

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=10005,inf=1e9;
    int n,m,q,h[N],cnt=1,s,t,le[N];
    struct qwe
    {
    	int ne,to,va;
    }e[N*100];
    int read()
    {
        int r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    void add(int u,int v,int w)
    {
        cnt++;
        e[cnt].ne=h[u];
        e[cnt].to=v;
        e[cnt].va=w;
        h[u]=cnt;
    }
    void ins(int u,int v,int w)
    {
        add(u,v,w);
        add(v,u,0);
    }
    bool bfs()
    {
        queue<int>q;
        memset(le,0,sizeof(le));
        le[s]=1,q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=h[u];i;i=e[i].ne)
                if(!le[e[i].to]&&e[i].va>0)
                {
                    le[e[i].to]=le[u]+1;
                    q.push(e[i].to);
                }
        }
        return le[t];
    }
    int dfs(int u,int f)
    {
        if(u==t||!f)
            return f;
        int us=0;
        for(int i=h[u];i&&us<f;i=e[i].ne)
            if(le[e[i].to]==le[u]+1&&e[i].va>0)
            {
                int t=dfs(e[i].to,min(e[i].va,f-us));
                e[i].va-=t;
                e[i^1].va+=t;
                us+=t;
            }
        if(!us)
            le[u]=0;
        return us;
    }
    int dinic()
    {
        int re=0;
        while(bfs())
            re+=dfs(s,inf);
        return re;
    }
    int main()
    {
    	n=read(),m=read(),q=read();
    	s=0,t=2*n+1;
    	for(int i=1;i<=m;i++)
    	{
    		int x=read(),y=read();
    		ins(x+n,y,inf),ins(y+n,x,inf);
    	}
    	ins(s,1+n,inf);//ins(1,1+n,inf);
    	for(int i=1;i<=n;i++)
    		ins(i,i+n,1);
    	for(int i=1;i<=q;i++)
    	{
    		int x=read();
    		ins(x,t,inf);
    	}
    	printf("%d
    ",dinic());
    	return 0;
    }
    
  • 相关阅读:
    Codeforces Round #229
    A Funny Game(博弈论)
    01背包模板
    一月24日新生冬季练习赛解题报告H.排列问题
    一月24日新生冬季练习赛解题报告F.棋盘
    POJ 2240Arbitrage
    POJ 3660Cow Contest
    POJ 3259Wormholes
    POJ 1860Currency Exchange
    HDU 4027Can you answer these queries?
  • 原文地址:https://www.cnblogs.com/lokiii/p/9016712.html
Copyright © 2020-2023  润新知