zoukankan      html  css  js  c++  java
  • BZOJ3504: [Cqoi2014]危桥

    BZOJ3504: [Cqoi2014]危桥

    Description

    Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。

    某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行。

    其中一些桥由于年久失修成为危桥,最多只能通行两次。

    Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2到al算一次往返)。

    同时,Bob希望在岛屿bl和b2之间往返bn次。

    这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。

    请问Alice和Bob能完成他们的愿望吗?

    Input

    本题有多组测试数据。
    每组数据第一行包含7个空格隔开的整数,分别为N、al、a2、an、bl、b2、bn。
    接下来是一个N行N列的对称矩阵,由大写字母组成。

    矩阵的i行j列描述编号i一1和j-l的岛屿间的连接情况,若为“O”则表示有危桥相连:为“N”表示有普通的桥相连:为“X”表示没有桥相连。

    Output

    对于每组测试数据输出一行,如果他们都能完成愿望输出“Yes”,否则输出“No”。

    Sample Input

    4 0 1 1 2 3 1
    XOXX
    OXOX
    XOXO
    XXOX
    4 0 2 1 1 3 2
    XNXO
    NXOX
    XOXO
    OXOX

    Sample Output

    Yes
    No
    数据范围
    4<=N<50
    O<=a1, a2, b1, b2<=N-1
    1 <=an. b<=50

    题解Here!
    许久没有碰过的网络流,感觉$Dinic$都不会敲了。。。
    网络流的关键是建图。
    这个题应该很容易想到建图方案。
    对于图上的任意一条边,如果有普通的桥相连,那么建一条流量为$MAX$的边。
    否则是危桥,连一条流量为$2$的边。
    然后把往返$a_n,b_n$次看成走$2 imes a_n,2 imes b_n$次。
    由超级源点$S$向$a_1,b_1$连流量分别为$2 imes a_n,2 imes b_n$的边。
    再由$a_2,b_2$向超级汇点$T$连流量分别为$2 imes a_n,2 imes b_n$的边。
    然后判断最大流是否为$2 imes(a_n+b_n)$即可。
    然后有个坑点:从$a_1$出发的流量可能会到$b_2$,从$b_!$出发的流量可能会到$a_2$。
    于是我们还要再建一遍,即:
    由超级源点$S$向$a_1,b_2$连边,由$a_2,b_1$向超级汇点$T$连边。
    然后判断两次最大流是否都等于$2 imes(a_n+b_n)$即可。
    注:节点编号是$[0,n-1]$。。。
    附代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define MAXN 110
    #define MAX 999999999
    using namespace std;
    int n,m,s,t,c,d;
    int head[MAXN],deep[MAXN];
    struct node1{
    	int next,to,w;
    }a[MAXN*MAXN];
    struct node2{
    	int u,v,w;
    }b[MAXN*MAXN];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline void clean(){
    	memset(head,0,sizeof(head));
    	memset(a,0,sizeof(a));
    	c=2;
    }
    inline void badd(int u,int v,int w){
    	d++;
    	b[d].u=u;b[d].v=v;b[d].w=w;
    }
    inline void add(int u,int v,int w){
    	a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
    	a[c].to=u;a[c].w=0;a[c].next=head[v];head[v]=c++;
    }
    bool bfs(){
    	int u,v;
    	queue<int> q;
    	for(int i=1;i<=t;i++)deep[i]=0;
    	deep[s]=1;
    	q.push(s);
    	while(!q.empty()){
    		u=q.front();
    		q.pop();
    		for(int i=head[u];i;i=a[i].next){
    			v=a[i].to;
    			if(a[i].w&&!deep[v]){
    				deep[v]=deep[u]+1;
    				if(v==t)return true;
    				q.push(v);
    			}
    		}
    	}
    	return false;
    }
    int dfs(int x,int limit){
    	if(x==t)return limit;
    	int v,sum,cost=0;
    	for(int i=head[x];i;i=a[i].next){
    		v=a[i].to;
    		if(a[i].w&&deep[v]==deep[x]+1){
    			sum=dfs(v,min(a[i].w,limit-cost));
    			if(sum>0){
    				a[i].w-=sum;
    				a[i^1].w+=sum;
    				cost+=sum;
    				if(cost==limit)break;
    			}
    			else deep[v]=-1;
    		}
    	}
    	return cost;
    }
    int dinic(){
    	int ans=0;
    	while(bfs())ans+=dfs(s,MAX);
    	return ans;
    }
    void init(){
    	char ch[MAXN];
    	int a1,a2,an,b1,b2,bn;
    	a1=read()+1;a2=read()+1;an=read()*2;
    	b1=read()+1;b2=read()+1;bn=read()*2;
    	d=0;
    	memset(b,0,sizeof(b));
    	for(int i=1;i<=n;i++){
    		scanf("%s",ch+1);
    		for(int j=1;j<=n;j++){
    			if(ch[j]=='X')continue;
    			else if(ch[j]=='O')badd(i,j,2);
    			else if(ch[j]=='N')badd(i,j,MAX);
    		}
    	}
    	clean();
    	for(int i=1;i<=d;i++)add(b[i].u,b[i].v,b[i].w);
    	add(s,a1,an);add(s,b1,bn);
    	add(a2,t,an);add(b2,t,bn);
    	int flow1=dinic();
    	clean();
    	for(int i=1;i<=d;i++)add(b[i].u,b[i].v,b[i].w);
    	add(s,a1,an);add(s,b2,bn);
    	add(a2,t,an);add(b1,t,bn);
    	int flow2=dinic();
    	if(flow1==an+bn&&flow2==an+bn)printf("Yes
    ");
    	else printf("No
    ");
    }
    int main(){
    	while(~scanf("%d",&n)){
    		s=n+1;t=n+2;
    		init();
    	}
    	return 0;
    }
    
     
  • 相关阅读:
    杂题之求1-100连续不重复整数中的缺少的一个数
    C语言之位运算
    程序员的激情其实是一种痛苦
    主机windwo7+虚拟机centos如何配置虚拟机可以上网,且与主机互ping通
    MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法
    一个web项目在myeclipse中add deployment时无法被识别出来的原因
    Hibernate中,将session绑定到线程时,在保存和查询数据的代码里,要正确的关闭session
    springframwork历史版本下载地址
    在web项目中使用cxf开发webservice,包含spring支持
    [转] Spring Security(01)——初体验
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9463324.html
Copyright © 2011-2022 走看看