zoukankan      html  css  js  c++  java
  • loj 1407(2-sat + 枚举 + 输出一组可行解 )

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27115

    思路:有一个trick要注意:当情况为 2 x y 时,可以推出当y留下时,x也必须留下。然后就是后面的k个限制关系,我们可以3^(k)次方枚举,一旦找到符合条件的就return 。然后就是反向建图,拓扑排序找可行解。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stack>
      6 #include<queue>
      7 #include<vector>
      8 #include<cmath>
      9 using namespace std;
     10 #define MAXN 2222
     11 
     12 int n,m,k;
     13 struct Node{
     14     int tag;
     15     int num[3];
     16 }node[7];
     17 
     18 vector<vector<int> >g,gg,edge;
     19 
     20 int cnt,bcc_count;
     21 int dfn[MAXN],low[MAXN],color[MAXN];
     22 int degree[MAXN];
     23 bool mark[MAXN];
     24 stack<int>S;
     25 
     26 void Tarjan(int u)
     27 {
     28     low[u]=dfn[u]=++cnt;
     29     mark[u]=true;
     30     S.push(u);
     31     for(int i=0;i<edge[u].size();i++){
     32         int v=edge[u][i];
     33         if(dfn[v]==0){
     34             Tarjan(v);
     35             low[u]=min(low[u],low[v]);
     36         }else if(mark[v]){
     37             low[u]=min(low[u],dfn[v]);
     38         }
     39     }
     40     if(low[u]==dfn[u]){
     41         int v;
     42         bcc_count++;
     43         do{
     44             v=S.top();
     45             S.pop();
     46             mark[v]=false;
     47             color[v]=bcc_count;
     48         }while(u!=v);
     49     }
     50 }
     51 
     52 int opp[MAXN];
     53 bool Check()
     54 {
     55     for(int i=1;i<=n;i++){
     56         if(color[i]==color[i+n])return false;
     57         opp[color[i]]=color[i+n];
     58         opp[color[i+n]]=color[i];
     59     }
     60     return true;
     61 }
     62 
     63 bool Judge()
     64 {
     65     int kk=(int)pow(3.0,k);
     66     for(int i=0;i<kk;i++){
     67         for(int j=1;j<=2*n;j++)edge[j]=g[j];
     68         int j=i,_count=0;
     69         while(_count<k){
     70             int id=j%3;
     71             int x=node[_count].num[id];
     72             if(node[_count].tag==1){
     73                 edge[x+n].push_back(x);
     74             }else 
     75                 edge[x].push_back(x+n);
     76             _count++;
     77             j/=3;
     78         }
     79         cnt=bcc_count=0;
     80         memset(dfn,0,sizeof(dfn));
     81         memset(mark,false,sizeof(mark));
     82         for(int j=1;j<=2*n;j++)if(dfn[j]==0)Tarjan(j);
     83         if(Check())return true;
     84     }
     85     return false;
     86 }
     87 
     88 int vis[MAXN];
     89 void TopSort()
     90 {
     91     queue<int>que;
     92     for(int i=1;i<=bcc_count;i++){
     93         if(degree[i]==0)que.push(i);
     94     }
     95     memset(vis,0,sizeof(vis));
     96     while(!que.empty()){
     97         int u=que.front();
     98         que.pop();
     99         if(vis[u]==0){
    100             vis[u]=1;
    101             vis[opp[u]]=-1;
    102         }
    103         for(int i=0;i<gg[u].size();i++){
    104             int v=gg[u][i];
    105             if(--degree[v]==0)que.push(v);
    106         }
    107     }
    108 }
    109 
    110 vector<int>ans;
    111 void Solve()
    112 {
    113     gg.clear();
    114     gg.resize(2*n+2);
    115     memset(degree,0,sizeof(degree));
    116     for(int u=1;u<=2*n;u++){
    117         for(int i=0;i<edge[u].size();i++){
    118             int v=edge[u][i];
    119             if(color[u]!=color[v]){
    120                 gg[color[v]].push_back(color[u]);
    121                 degree[color[u]]++;
    122             }
    123         }
    124     }
    125     TopSort();
    126     ans.clear();
    127     for(int i=1;i<=n;i++)
    128         if(vis[color[i]]==1)ans.push_back(i);
    129     printf("%d",(int)ans.size());
    130     for(int i=0;i<(int)ans.size();i++){
    131         printf(" %d",ans[i]);
    132     }
    133     puts(".");
    134 }
    135 
    136 int main()
    137 {
    138     int _case,x,y,z,tag,t=1;
    139     scanf("%d",&_case);
    140     while(_case--){
    141         scanf("%d%d%d",&n,&m,&k);
    142         g.clear();
    143         g.resize(2*n+2);
    144         edge.clear();
    145         edge.resize(2*n+2);
    146         while(m--){
    147             scanf("%d%d%d",&tag,&x,&y);
    148             if(tag==1)g[x+n].push_back(y),g[y+n].push_back(x);
    149             else if(tag==2)g[x+n].push_back(y+n),g[y].push_back(x);
    150             else if(tag==3)g[x].push_back(y+n),g[y].push_back(x+n);
    151             else g[x].push_back(y+n),g[y].push_back(x+n),g[x+n].push_back(y),g[y+n].push_back(x);
    152         }
    153         for(int i=0;i<k;i++){
    154             scanf("%d%d%d%d",&node[i].tag,&node[i].num[0],&node[i].num[1],&node[i].num[2]);
    155         }
    156         printf("Case %d: ",t++);
    157         if(Judge()){
    158             printf("Possible ");
    159             Solve();
    160         }else 
    161             puts("Impossible.");
    162     }
    163     return 0;
    164 }
    165         
    View Code
  • 相关阅读:
    Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)
    C#反射通过类名的字符串获取生成对应的实例
    在Core环境下用WebRequest连接上远程的web Api 实现数据的简单CRUD(续)
    从零开始构建一个的asp.net Core 项目(二)
    从零开始构建一个的asp.net Core 项目(一)
    eNSP自学入门(基础)
    在Core环境下用WebRequest连接上远程的web Api 实现数据的简单CRUD(附Git地址)
    Asp .net core api+Entity Framework core 实现数据CRUD数据库中(附Git地址)
    重构--去除丑陋的switch语句
    ASP .NET core 入门基础内容备份
  • 原文地址:https://www.cnblogs.com/wally/p/3337535.html
Copyright © 2011-2022 走看看