图论:二分图判定

我其实只是想练一练二分图判定的,但是翻到了一个这么个题。。

双栈排序早有耳闻,非常欣赏当年的出题水平,堪称经典

这个题AC的人一定是个天才

废话不多说,双栈排序的思路我就不介绍了,没有那个水平,直接来说说怎么二分图染色

bool color(int x,int cl)
{
    c[x]=cl;
    for(int tmp=g[x];tmp;tmp=e[tmp].next)
    {
        if(!c[e[tmp].t])
            {if(!color(e[tmp].t,3-cl)) return 0;}
        else if(c[e[tmp].t]==cl) return 0;
    }
    return 1;
}

这个方法,14年的时候练了很多次,当时习惯写BFS的,可能是因为所有点都要跑所以无所谓了吧

每个点都调用一次color,初始cl传1,进来的时候如果这个点没有染过色,就给它染上cl这个颜色

然后判断所有出边所连接的点,如果有相邻且同色的,直接GG

否则,染色为3-cl,这是一个小技巧,cl这时取值为1或2,十分方便

好了,二分图判定说完了,贴上双栈排序的代码跑路了

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int INF=1000000000;
 5 const int maxn=1005;
 6 int cnt,n,t1,t2;
 7 int a[maxn],g[maxn],c[maxn],f[maxn],s1[maxn],s2[maxn];
 8 struct Edge{int t,next;}e[maxn*maxn];
 9 void addedge(int u,int v)
10 {
11     e[++cnt].t=v;e[cnt].next=g[u];
12     g[u]=cnt;
13 }
14 bool color(int x,int cl)
15 {
16     c[x]=cl;
17     for(int tmp=g[x];tmp;tmp=e[tmp].next)
18     {
19         if(!c[e[tmp].t])
20             {if(!color(e[tmp].t,3-cl)) return 0;}
21         else if(c[e[tmp].t]==cl) return 0;
22     }
23     return 1;
24 }
25 int read()
26 {
27     int x=0,f=1;char ch=getchar();
28     while(ch<'0'||ch>'9') {if(ch=='-')f=-1; ch=getchar();}
29     while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
30     return x*f;
31 }
32 int main()
33 {
34     n=read();
35     for(int i=1;i<=n;i++) a[i]=read();
36     f[n+1]=INF;
37     for(int i=n;i;i--) f[i]=min(f[i+1],a[i]);
38     for(int i=1;i<=n;i++)
39         for(int j=i+1;j<=n;j++)
40             if(a[i]<a[j]&&f[j+1]<a[i]) addedge(i,j),addedge(j,i);
41     for(int i=1;i<=n;i++)
42         if(!c[i])
43             if(!color(i,1)) {puts("0");return 0;}
44     int now=1;
45     for(int i=1;i<=n;i++)
46     {
47         if(c[i]==1) printf("a "),s1[++t1]=a[i];
48         else printf("c "),s2[++t2]=a[i];
49         while(s1[t1]==now||s2[t2]==now)
50         {
51             if(s1[t1]==now) printf("b "),t1--;
52             else printf("d "),t2--;
53             now++;
54         }
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/aininot260/p/9433981.html