• Ural 1382 2SAT


    ural1382 直接套用 2SAT模板

    缩点 拓扑排序。。。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<algorithm>
    //2SAT问题  准确判断矛盾边 不必考虑推出的边是否存在矛盾!! 
    using namespace std;
    const int maxn=(1000+1);
    vector<int>po[maxn*2],ps[maxn*2],strong[maxn*2];
    bool vis[maxn*2],added[maxn*2][maxn*2];
    int n,a[maxn],b[maxn],c[maxn],tot=0,color[maxn*2],du[maxn*2],point[maxn*2];
    stack<int>s;
    void add(int b,int a)
    {
     if(added[b][a])return;
     	else added[b][a]=true;
     po[a].push_back(b);
     ps[b].push_back(a);
    }
    void dfs1(int cur,int fa)
    {
     vis[cur]=true;
     for(int i=0;i<po[cur].size();i++)
     	{
     	 int np=po[cur][i];
    	 if(np==fa||vis[np])continue;
    	 dfs1(np,cur);	
    	}
     s.push(cur);
    }
    void  dfs2(int cur,int co,int fa)
    {
     strong[co].push_back(cur);
     color[cur]=co;
     for(int i=0;i<ps[cur].size();i++)
     	{
     	 int np=ps[cur][i];
     	 if(np==fa||(color[np]))continue;
     	 dfs2(np,co,cur);
    	}
    }
    void strongconnect()
    {
     memset(vis,0,sizeof(vis));memset(color,0,sizeof(color));
     for(int i=1;i<=n*2;i++)
        if(!vis[i])dfs1(i,-1);	
     tot=1;
     while(!s.empty())
     	{
     	 int np=s.top();
     	 s.pop();
     	 if(color[np])continue;
     	 dfs2(np,tot++,-1);
    	}
    }
    bool cmp(int a,int b)
    {
     return du[a]<du[b];
    }
    int  topo(int ans[])
    {
     for(int i=1;i<tot;i++)
     	point[i]=i;
     bool anss=1;
     for(int i=1;i<tot;i++)
     	{
     	 sort(point+i,point+tot,cmp);
     	 int np=point[i];
     	 if(du[np]>0)return -1;
     	 if(du[np]==du[point[i+1]]&&i+1<tot)anss=0;
     	 ans[i]=np;
     	 for(int j=0;j<ps[np].size();j++)
     	 	du[ps[np][j]]--;
    	}	
    }
    int main()
    {
     freopen("t.txt","r",stdin);
     scanf("%d",&n);
     for(int i=1;i<=n;i++)
     	scanf("%d%d%d",&a[i],&b[i],&c[i]);
     for(int i=1;i<=n;i++)
     	for(int j=1;j<=n;j++)
     		{
     		 if(i==j)continue;
     		 if(a[i]==a[j])
     		 	{
     		 	 add(j*2,i*2-1);
     		 	 add(i*2,j*2-1);
    			}
    		 if(i==b[j])
    		 	{
    		 	 add(i*2,j*2);
    		 	 add(j*2-1,i*2-1);
    			}
    		 if(b[i]==b[j])
    		 	{
    		 	 add(i*2-1,j*2);
    		 	 add(j*2-1,i*2);
    			}
    		 if((a[i]==c[j]&&i!=b[j]))
    		 	{
    		 	 add(i*2,j*2);
    		 	 add(j*2-1,i*2-1);
    			}
    		}
     strongconnect();
     
     for(int i=1;i<tot;i++)
     	{
     	 memset(vis,0,sizeof(vis));
     	 ps[i].clear();
     	 for(int j=0;j<strong[i].size();j++)
     	 	{
     	 	 int np=strong[i][j];
     	 	 for(int k=0;k<po[np].size();k++)
     	 	 	{
     	 	 	 int nc=color[po[np][k]];
     	 	 	 if(nc==i)continue;
     	 	 	 if(vis[nc]){continue;}
     	 	 	 	else{vis[nc]=true;ps[i].push_back(nc);du[nc]++;}
    			}
    		}
    	}
     int ans[maxn*2];
     topo(ans);
     int anss[maxn];
     for(int i=	tot-1;i>=1;i--)
     	{
     	 int np=ans[i];
     	 for(int i=0;i<strong[np].size();i++)
     	 	{
     	 	 int npp=strong[np][i];
     	 	if(anss[(npp+1)/2]==0) anss[((npp+1)/2)]=(npp+1)%2+1;
    		}
    	}
     for(int i=1;i<n;i++)
     	printf("%d ",anss[i]);
     printf("%d
    ",anss[n]);
      return 0;
    }
    

      

  • 相关阅读:
    Tinyhttpd 代码学习
    Windows noinstall zip 安装MySQL。
    Java 优先队列
    Java Comparable 和 Comparator
    Centos6.6下安装Python3.5
    对象的实现
    对象接口
    适配器模式
    java基础学习(一)
    【MongoDB】如何注册windows服务
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6758259.html
Copyright © 2020-2023  润新知