zoukankan      html  css  js  c++  java
  • hud 3062 Party

    题意:中文的,不解释了

    思路:2-sat基本题,练习的第一道题目,网上找了个模板

    话说这个vector< vector<int> >还真是弄了好久的,所以先

    写了一个一维的弄了好久好久……2-sat终于有点思路了,各种错啊……

    这个是一维的:

    #include<iostream>
    #include<string>
    #include<vector>
    #include<stack>
    #include <cstdio>
    #include<algorithm>
    #include <cstring>
    using namespace std;

    const int N=2005;

    vector<int>map1[N];
    vector<int>map2[N];

    bool used[N],flag[N][N];

    int order[N],id[N];
    int m,n,cnt,color;

    void Init()
    {
    for(int i=0;i<2*n;i++)
    {
    map1[i].clear();
    map2[i].clear();
    }
    }

    void addedge(int from,int to)
    {
    map1[from].push_back(to);
    map2[to].push_back(from);
    }

    void build_map1()
    {
    int i,x,y,u,v,uu,vv;
    for(i=0;i<m;i++)
    {
    scanf("%d%d%d%d",&x,&y,&u,&v);
    u=2*x+u;
    uu=(u%2)?u-1:u+1;
    v=2*y+v;
    vv=(v%2)?v-1:v+1;
    addedge(u,vv);
    addedge(v,uu);
    }
    }

    void dfs1(int u) //把所有的点正向压缩
    {
    used[u]=true;
    for(int i=0;i<map1[u].size();i++)
    if(!used[map1[u][i]])
    dfs1(map1[u][i]);
    order[cnt++]=u;
    }

    void dfs2(int u)
    {
    used[u]=true;
    id[u]=color;
    for(int i=0;i<map2[u].size();i++)
    if(!used[map2[u][i]])
    dfs2(map2[u][i]);
    }

    bool sat()
    {
    int i;
    memset(used,0,sizeof(used));
    color=cnt=0;
    for(i=0;i<2*n;i++)
    if(!used[i])
    dfs1(i);
    memset(used,0,sizeof(used));
    for(i=cnt-1;i>=0;i--)
    if(!used[order[i]])
    {
    color++;
    dfs2(order[i]);
    }
    for(i=0;i<2*n;i+=2)
    if(id[i]==id[i+1])
    return 0;
    return 1;
    }


    int main()
    {
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    if(n==0&&m==0)
    break;
    Init();
    build_map1();
    if(!sat())
    printf("NO\n");
    else
    printf("YES\n");
    }
    return 0;
    }
    /*
    这个是二维的:

    */

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    using namespace std;
    const int Maxn=2010;//2*N
    bool visit[Maxn];//标记
    vector< vector<int> > adj;//正向图
    vector< vector<int> > radj;//逆向图
    int n,m,cnt,id[Maxn],order[Maxn];
    //n表示点对数,m表示矛盾,id[]表示缩点后点对应的新点的标号
    //order[]是强连通时使用korasaju记录搜索的次序
    void Init()
    {
    for(int i=0; i<2*n; i++)
    {
    adj[i].resize(Maxn);
    radj[i].resize(Maxn);
    }
    }
    void init()
    {
    for(int i=0; i<2*n; i++)
    {
    adj[i].clear();
    radj[i].clear();
    }
    }

    void AddEdge(int from, int to)
    {
    adj[from].push_back(to);
    radj[to].push_back(from);
    }

    void BuildGraph()
    {
    int u, v, x, y;
    for(int i=0; i<m; i++)
    {
    scanf("%d%d%d%d", &x, &y, &u, &v);
    u=2*x+u;
    int uu=(u%2)?u-1:u+1;
    v=2*y+v;
    int vv=(v%2)?v-1:v+1;
    AddEdge(u, vv);
    AddEdge(v, uu);
    }
    }
    void dfs(int u)//求强联通时的正向搜索进行标号
    {
    visit[u]=true;
    int i,len=adj[u].size();
    for(i=0; i<len; i++)
    if(!visit[adj[u][i]])
    dfs(adj[u][i]);
    order[cnt++]=u;//标号从0开始,上面的点后标号,表示从正向的边存在
    }

    void rdfs(int u)//求强联通的逆向搜索
    {
    id[u]=cnt;//进行缩点标记
    visit[u]=true;
    int i,len=radj[u].size();
    for(i=0; i<len; i++)
    if(!visit[radj[u][i]])
    rdfs(radj[u][i]);
    }

    void korasaju()
    {
    int i;
    memset(visit,false,sizeof(visit));
    for(cnt=0,i=0; i<2*n; i++) //正向搜一次
    if(!visit[i])
    dfs(i);
    memset(id,0,sizeof(id));
    memset(visit,false,sizeof(visit));
    for(cnt=0,i=2*n-1; i>=0; i--) //从正向标记大的逆向搜一次.表示逆向的边也存在
    {
    if(!visit[order[i]])
    {
    cnt++;
    rdfs(order[i]);//缩点后点的标号从1开始
    }
    }
    }

    bool solve()//判断同样的缩点中是否有矛盾的点
    {
    for(int i=0; i<2*n; i+=2)
    if(id[i]==id[i+1])
    return false;
    return true;
    }

    int main()
    {
    adj.resize(Maxn);
    radj.resize(Maxn);
    Init();
    while(scanf("%d%d", &n, &m)!=EOF)
    {
    init();
    BuildGraph();
    korasaju();
    if(!solve()) puts("NO");
    else puts("YES");
    }
    return 0;
    }
    作者:FreeAquar
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    前沿技术解密——VirtualDOM
    Ques核心思想——CSS Namespace
    Unix Pipes to Javascript Pipes
    Road to the future——伪MVVM库Q.js
    聊聊CSS postproccessors
    【译】十款性能最佳的压缩算法
    Kafka Streams开发入门(9)
    Kafka Streams开发入门(8)
    【译】Kafka Producer Sticky Partitioner
    【译】99th Percentile Latency at Scale with Apache Kafka
  • 原文地址:https://www.cnblogs.com/FreeAquar/p/2104207.html
Copyright © 2011-2022 走看看