zoukankan      html  css  js  c++  java
  • 1182. Team Them Up! 夜

    http://acm.timus.ru/problem.aspx?space=1&num=1182

    比较麻烦的一道题

    先将不是相互知道的两个人重新建边 A知道B 但B不知道A 也需要建边(双向边)

    新的图是m个连同块  对于每个连同块 用bfs将他们分成两组 组1 和组2 如果分的过程中出现矛盾 则无解

    否则就会有m对  然后根据这m对 用DP的思想求最优解 既可

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    #include<stack>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const int INF=0x3f3f3f3f;
    //priority_queue<int,vector<int>,greater<int> >qt;
    const int N=205;
    bool know[N][N];
    vector<int>graph1[N];
    vector<int>graph2[N];
    int choose[N][N];
    int head[N],I;
    struct node
    {
        int j,next;
    }side[N*N];
    int in[N];
    void add(int i,int j)
    {
        side[I].j=j;
        side[I].next=head[i];
        head[i]=I++;
    }
    bool bfs(int s,int m)
    {
        in[s]=1;
        graph1[m].push_back(s);
        queue<int>qt;
        qt.push(s);
        while(!qt.empty())
        {
            int x=qt.front();
            qt.pop();
            for(int t=head[x];t!=-1;t=side[t].next)
            {
                int j=side[t].j;
                if(in[j]==0)
                {
                    if(in[x]==1)
                    {in[j]=2;graph2[m].push_back(j);}
                    if(in[x]==2)
                    {in[j]=1;graph1[m].push_back(j);}
                    qt.push(j);
                }else if(in[j]==in[x])
                {
                    return false;
                }
            }
        }
        return true;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n;
        while(cin>>n)
        {
            memset(know,false,sizeof(know));
            for(int i=1;i<=n;++i)
            {
                int j;
                while(cin>>j)
                {
                    if(!j) break;
                    know[i][j]=true;
                }
            }
            memset(head,-1,sizeof(head));
            I=0;
            for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
            if(!know[i][j]||!know[j][i])
            {add(i,j);add(j,i);}
            memset(in,0,sizeof(in));
            for(int i=0;i<=n;++i)
            {graph1[i].clear();graph2[i].clear();}
            int flag=true;
            int m=0;
            for(int i=1;i<=n;++i)
            if(in[i]==0&&!bfs(i,m++))
            {flag=false;break;}
            if(flag==false)
            {cout<<"No solution"<<endl;continue;}
            memset(choose,0,sizeof(choose));
            stack<int>stx[2];
            stack<int>sty[2];
            stx[0].push(0);
            sty[0].push(0);
            int X,Y,x,y;
            for(int i=0;i<m;++i)
            {
                int l=i%2;
                int k=(i+1)%2;
                while(!stx[l].empty())
                {
                    x=stx[l].top();stx[l].pop();
                    y=sty[l].top();sty[l].pop();
                    X=x+graph1[i].size();
                    Y=y+graph2[i].size();
                    if(choose[X][Y]==0)
                    {choose[X][Y]=1;stx[k].push(X);sty[k].push(Y);}
                    X=x+graph2[i].size();
                    Y=y+graph1[i].size();
                    if(choose[X][Y]==0)
                    {choose[X][Y]=2;stx[k].push(X);sty[k].push(Y);}
                }
            }
            int MAX=INF;
            while(!stx[m%2].empty())
            {
                x=stx[m%2].top();stx[m%2].pop();
                y=sty[m%2].top();sty[m%2].pop();
                if(abs(x-y)<MAX)
                {
                    MAX=abs(x-y);
                    X=x;
                    Y=y;
                }
            }
            vector<int>ans1;
            vector<int>ans2;
            while(X||Y)
            {
                --m;
                if(choose[X][Y]==1)
                {
                    ans1.insert(ans1.end(),graph1[m].begin(),graph1[m].end());
                    ans2.insert(ans2.end(),graph2[m].begin(),graph2[m].end());
                    X=X-graph1[m].size();
                    Y=Y-graph2[m].size();
                }else
                {
                    ans2.insert(ans2.end(),graph1[m].begin(),graph1[m].end());
                    ans1.insert(ans1.end(),graph2[m].begin(),graph2[m].end());
                    X=X-graph2[m].size();
                    Y=Y-graph1[m].size();
                }
            }
            cout<<ans1.size();
            for(unsigned int i=0;i<ans1.size();++i)
            cout<<" "<<ans1[i];
            cout<<endl;
            cout<<ans2.size();
            for(unsigned int i=0;i<ans2.size();++i)
            cout<<" "<<ans2[i];
            cout<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    HDU 4972 A simple dynamic programming problem
    dd usb 启动盘制作 成功版本
    1233
    openstack kvm 虚拟机磁盘差异衍生
    怎样安装g++/gdb
    区间最小值 线段树 (2015年 JXNU_ACS 算法组暑假第一次周赛)
    hdu
    TCP/IP解析(一):TCP/IP的工作方式
    使用Python生成源文件的两种方法
    zoj1003 Crashing Balloon
  • 原文地址:https://www.cnblogs.com/liulangye/p/2791377.html
Copyright © 2011-2022 走看看