• 2199: [Usaco2011 Jan]奶牛议会 2-sat


    链接

    https://www.luogu.org/problemnew/show/P3007
    https://www.lydsy.com/JudgeOnline/problem.php?id=2199

    思路

    建图,缩点tarjan
    判断impossible
    之后就不是输出方案的套路了
    判断Y 、N、?
    直接暴力枚举点的两种情况(i,i+n)是否能dfs到一块
    不能就是互不牵制,是?
    其他就是Y 或 N

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+7;
    int read() {
    	int x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    int n,m;
    struct node {
    	int v,nxt;
    }e[N<<1];
    int head[N<<1],tot;
    void add(int u,int v) {
    	e[++tot].v=v;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    int stak[N],top,cnt,belong[N],low[N],dfn[N],vis[N];
    void tarjan(int u) {
    	low[u]=dfn[u]=++cnt;
    	stak[++top]=u;
    	vis[u]=1;
    	for(int i=head[u];i;i=e[i].nxt) {
    		int v=e[i].v;
    		if(!dfn[v]) {
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		} else if(vis[v]) {
    			low[u]=min(low[u],dfn[v]);
    		}
    	}
    	if(low[u]==dfn[u]) {
    		++belong[0];
    		while(stak[top]!=u) {
    			vis[stak[top]]=0;
    			belong[stak[top]]=belong[0];		
    			top--;
    		} top--;
    		vis[u]=0;
    		belong[u]=belong[0];
    	}
    }
    vector<int> G[N];
    int dfs(int u,int goal) {
    	if(u==goal) return 1;
    	for(vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) {
    		if(dfs(*it,goal)) return 1;
    	}
    	return 0;
    }
    void solve(int id) {
    //	cout<<belong[id]<<" "<<belong[id+n]<<"<
    ";
    	int a=dfs(belong[id],belong[id+n]);
    	int b=dfs(belong[id+n],belong[id]);
    	if(!a&&!b) printf("?");
    	if(b) printf("Y");
    	if(a) printf("N");
    }
    int main() {
    //	freopen("a.in","r",stdin);
    	n=read(),m=read();
    	for(int k=1;k<=m;++k) {
    		//read
    		//begin 
    		char s;
    		int i,j,x,y;
    		i=read();
    		s=getchar();
    		while(s==' ') s=getchar();
    		x= s=='Y' ? 1 : 0;
    		j=read();
    		s=getchar();
    		while(s==' ') s=getchar();
    		y= s=='Y' ? 1 : 0;
    		//end
    		add(n*x+i,n*(y^1)+j);
    		add(n*y+j,n*(x^1)+i);
    	}
    	for(int i=1;i<=2*n;++i) 
    		if(!dfn[i])
    			tarjan(i);
    	for(int i=1;i<=n;++i) {
    		if(belong[i]==belong[i+n]) {
    			puts("IMPOSSIBLE");
    			return 0;
    		}
    	}
    	for(int i=1;i<=2*n;++i) {
    		for(int j=head[i];j;j=e[j].nxt) {
    			if(belong[i]!=belong[e[j].v]) {
    				G[belong[i]].push_back(belong[e[j].v]);
    			}
    		}
    	}
    	for(int i=1;i<=n;++i) solve(i);
    	return 0;
    }
    
  • 相关阅读:
    提问必备-如何有效的提问?
    通过jdbc驱动连接thriftserver
    在idea上使用springboot构建ssm项目(一)
    二柱子与他的计算题
    JavaScript
    表单格式化
    2020.10.09
    HTML书写规范
    下拉列表框 JComboBox
    用户登录界面
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10408032.html
Copyright © 2020-2023  润新知