zoukankan      html  css  js  c++  java
  • bzoj 3504: [Cqoi2014]危桥【最大流】

    首先能显然的想到一个方法:(s,a1,an)(a2,t,an)(s,b1,bn)(b2,t,bn)然后图中的边正常连,危桥流量1,正常桥流量为inf。但是这样即使满流了也会有一些问题,就是流是从a1到b2的。解决方法是交换b1和b2,再跑一遍,这样以来如果再次满流,那么就意味着a1,a2,b1,b2要么是(a1,a2),(b1,b2)联通,要么是联通的。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=1000005,inf=1e9;
    int n,a1,a2,an,b1,b2,bn,s,t,cnt,h[N],le[N];
    char c[105][105];
    struct qwe
    {
    	int ne,to,va;
    }e[N<<1];
    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)
    {//cout<<u<<" "<<v<<endl;
    	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(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(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;
    }
    bool ok(int a1,int a2,int b1,int b2)
    {
    	memset(h,0,sizeof(h));
    	cnt=1;s=0,t=n+1;
    	ins(s,a1,an);
    	ins(s,b1,bn);
    	ins(a2,t,an);
    	ins(b2,t,bn);//cout<<c[3][4]<<endl;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    		{
    			if(c[i][j]=='N')
    				ins(i,j,inf);
    			if(c[i][j]=='O')
    				ins(i,j,1);//,cout<<i<<" "<<j<<endl;;
    		}
    	return dinic()==an+bn;
    }
    int main()
    {
    	while(~scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn))
    	{
    		for(int i=1;i<=n;i++)
    			scanf("%s",c[i]+1);
    		if(ok(a1+1,a2+1,b1+1,b2+1)&&ok(a1+1,a2+1,b2+1,b1+1))
    			puts("Yes");
    		else
    			puts("No");
    	}
    	return 0;
    }
    /*
    4 0 1 1 2 3 1
    XOXX
    OXOX
    XOXO
    XXOX
    4 0 2 1 1 3 2
    XNXO
    NXOX
    XOXO
    OXOX
    */
    
  • 相关阅读:
    前端战五渣学前端——跨域
    CSS3学习笔记
    Vue工程化入口文件main.js中Vue.config.productionTip = false含义
    CSS选择器有哪几种?举例轻松理解CSS选择器
    研究生综合英语 作文 作业
    tomcat部署项目的方法
    【Winfrom-无边框窗体】Winform如何拖动无边框窗体?
    C#调用默认浏览器打开网页的几种方法
    CefSharp在高DPI的屏幕上出现黑边(winform)
    c# 关于mongo bson转json的问题
  • 原文地址:https://www.cnblogs.com/lokiii/p/8433469.html
Copyright © 2011-2022 走看看