poj2942 點-雙聯通+二分圖染色

來源:互聯網
上載者:User

標籤:之間   vector   hid   沒有   ems   mat   fine   make   stl   

題意:有一群騎士要坐在一個圓形的桌子上,他們之間有些人相互討厭,所以不能挨著,要求算出一次也不能坐在桌子上的人,每次會議桌子必須奇數個人,一個人不能開會

題解:可以先建一個補圖,要滿足題目條件我們只要找出所有奇圈(奇數個點的環),求出點-雙聯通分量,對於每一個單獨的點-雙連通分量,如果它一定是一個奇圈,那麼不能夠通過二分圖染色,可以通過畫圖驗證這條結論,那麼我們對於所有的奇圈裡的點進行染色,最後輸出沒有染色過的點,因為有可能會出現多次染色的點,所以不能直接每次加點數

坑點:不能用stl,tle了好多發,最後把所有的vector,map都換成了數組就過了,不能用vector存圖,那麼就用我最喜歡的鏈式前向星吧= = 

#include<map>#include<set>#include<list>#include<cmath>#include<queue>#include<stack>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define fi first#define se second#define mp make_pair#define pb push_back#define pii pair<int,int>#define C 0.5772156649#define pi acos(-1.0)#define ll long long#define mod 1000000007#define ls l,m,rt<<1#define rs m+1,r,rt<<1|1using namespace std;using namespace __gnu_cxx;const double g=10.0,eps=1e-7;const int N=1000+10,maxn=1000000+10,inf=0x3f3f3f;struct edge{    int to,Next;}e[maxn];int bcc[N];int index,num;int cnt,head[N];int dfn[N],low[N];int bccno[N];struct ewedge{int from,to;};stack<ewedge>s;bool ma[N][N];int in[N],ok[N];int color[N];bool notsub;void add(int x,int y){    e[cnt].to=y;    e[cnt].Next=head[x];    head[x]=cnt++;    e[cnt].to=x;    e[cnt].Next=head[y];    head[y]=cnt++;}void dfs(int u,int f,int p){    if(notsub)return ;    color[u]=p;    int c=3-p;    for(int i=head[u];~i;i=e[i].Next)    {        int x=e[i].to;        if(ok[x])        {            if(!color[x])dfs(x,u,c);            else            {                if(color[x]!=c)notsub=1;            }        }    }}void tarjan(int u,int f){    low[u]=dfn[u]=++index;    for(int i=head[u];~i;i=e[i].Next)    {        int x=e[i].to;        ewedge e=(ewedge){u,x};        if(x==f)continue;        if(!dfn[x])        {            s.push(e);            tarjan(x,u);            low[u]=min(low[u],low[x]);            if(low[x]>=dfn[u])            {                int res=0;                num++;                memset(ok,0,sizeof ok);                int be=0;                for(;;)                {                    ewedge p=s.top();s.pop();                    if(bccno[p.from]!=num)                    {                        bcc[res++]=p.from;                        be=p.from;                        bccno[p.from]=num;                        ok[p.from]=1;                    }                    if(bccno[p.to]!=num)                    {                        bcc[res++]=p.to;                        be=p.to;                        bccno[p.to]=num;                        ok[p.to]=1;                    }                    if(p.from==e.from&&p.to==e.to)break;                }                //判斷是不是二分圖                for(int i=0;i<res;i++)                    color[bcc[i]]=0;                notsub=0;                dfs(be,-1,1);                if(notsub)                {                    for(int i=0;i<res;i++)                        in[bcc[i]]=1;                }              /*  cout<<notsub<<"--------";                for(int j=0;j<bcc.size();j++)                    cout<<bcc[j]<<" ";                cout<<endl;*/            }        }        else        {            if(dfn[x]<dfn[u])low[u]=min(low[u],dfn[x]);        }    }}void init(int n){    memset(head,-1,sizeof head);    memset(ma,0,sizeof ma);    for(int i=1;i<=n;i++)    {        bccno[i]=dfn[i]=low[i]=in[i]=0;    }    while(!s.empty())s.pop();    index=num=cnt=0;}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        if(!n&&!m)break;        init(n);        while(m--)        {            int a,b;            scanf("%d%d",&a,&b);            ma[a][b]=ma[b][a]=1;        }        for(int i=1;i<=n;i++)            for(int j=i+1;j<=n;j++)                if(!ma[i][j])                    add(i,j);        for(int i=1;i<=n;i++)            if(!dfn[i])                tarjan(i,-1);        int ans=0;        for(int i=1;i<=n;i++)            if(in[i])                ans++;        printf("%d\n",n-ans);    }    return 0;}/************************/
View Code

 

poj2942 點-雙聯通+二分圖染色

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.