• bzoj 3504: [Cqoi2014]危桥【最大流】


    妙啊,很容易想到连(s,a1,an)(s,b1,bn)(a2,t,an)(b2,t,bn),这样,但是可能会发生a1流到b2或者b1流到a2这种不合法情况
    考虑跑两次,第二次交换b1b2,如果两次都合法就是合法
    证明是假设a1流到b2了x的流量,然后交换b1b2之后依然满足条件,那么一定可以有a1流到b1了x的流量的最大流,因为是无向图,所以a1流到b2了x的流量可以看做b2流到a1了x的流量,然后连起来就是b1流到b2了x的流量,也就是把不合法的x流量归到合法

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=105;
    int n,a1,a2,an,b1,b2,bn,h[N],cnt=1,le[N],s,t;
    char c[N][N];
    struct qwe
    {
    	int ne,to,va;
    }e[N*N];
    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()
    {
    	memset(le,0,sizeof(le));
    	queue<int>q;
    	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(e[i].va>0&&!le[e[i].to])
    			{
    				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(e[i].va>0&&le[e[i].to]==le[u]+1)
    		{
    			int t=dfs(e[i].to,min(f-us,e[i].va));
    			e[i].va-=t;
    			e[i^1].va+=t;
    			us+=t;
    		}
    	if(!us)
    		le[u]=0;
    	return us;
    }
    int dinic()
    {
    	int r=0;
    	while(bfs())
    		r+=dfs(s,1e9);
    	return r;
    }
    bool ok(int a1,int a2,int an,int b1,int b2,int bn)
    {
    	s=0,t=n+1,cnt=1;
    	memset(h,0,sizeof(h));
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			if(c[i][j]!='X')
    				ins(i,j,c[i][j]=='O'?1:1e9);
    	ins(s,a1,an);
    	ins(s,b1,bn);
    	ins(a2,t,an);
    	ins(b2,t,bn);
    	return dinic()==an+bn;
    }
    int main()
    {
    	while(~scanf("%d",&n))
    	{
    		scanf("%d%d%d%d%d%d",&a1,&a2,&an,&b1,&b2,&bn);
    		a1++,a2++,b1++,b2++;
    		for(int i=1;i<=n;i++)
    			scanf("%s",c[i]+1);
    		if(ok(a1,a2,an,b1,b2,bn)&&ok(a1,a2,an,b2,b1,bn))
    			puts("Yes");
    		else
    			puts("No");
    	}
    	return 0;
    }
    
  • 相关阅读:
    spin lock自旋锁 双链表操作(多线程安全)(Ring0)
    Interlocked单向链式栈
    自旋锁(Spin Lock)
    可等待定时器(获取系统时间)
    APC注入(Ring3)
    IOCP IO完成端口
    异步设备IO OVERLAPPED结构(设备内核对象 事件内核对象 可提醒IO)
    读写锁 SRWLOCK
    shell查看进程
    linux dmesg命令
  • 原文地址:https://www.cnblogs.com/lokiii/p/10803071.html
Copyright © 2020-2023  润新知