您的位置:首页 > 其它

判断图是否是二分图

2015-07-19 18:32 295 查看
之前GCJ2014practice遇到过,当时推我google的liuchenheng大神说这个是最基础的题,

如果不会,就别来面了。我还真不会,可见有多弱。然后EMC summer campus时遇到USTC的李晨讯,看到输入,我一看就知道这题,他说他也写了半天才A的。

看来这种基础题需要熟练了,不仅要写出来,而且要快!
https://code.google.com/codejam/contest/2933486/dashboard
这题是裸的直接判是否是二分图,加一个color数组用染色的方法来判,是否可二染色,这是一个技巧

unordered_map<string,int> StrIndex;
int color[maxn];//0 not visit, 1 color1, 2 color2
vector<int> Edge[maxn];
int n, m;

bool dfs(int cur, int c)
{
    if(color[cur]) return 1;
    color[cur]=c;
    for(auto i : Edge[cur]){
        if(color[cur]==color[i] || (!color[i] &&!dfs(i,3-c))) return 0;
    }
    return 1;
}
/*
void dfs1(int cur, int c, int cnt){
    color[cur]=c;
    if(cnt==n){
        int cnt1=0;
        for(int i=1;i<=n;i++){
            if(color[i]==1) cnt1++;
        }
        ans=max(cnt1, n-cnt1);
        return ;
    }
    for(auto i: Edge[cur]){
        if(color[cur]==color[i]) continue;
        dfs1(i, 3-c, cnt+1);
    }
}
*/
string str1, str2;
int main()
{

#ifndef ONLINE_JUDGE
    freopen ("A-small-practice-2.in" , "r" , stdin);
    freopen ("A-small-practice-2.out" , "w" , stdout);
#endif

    int t;
    cin>>t;
    for(int ti=1;ti<=t;ti++)
    {
        StrIndex.clear();
        n=0;
        memset(color,0,sizeof color);
        for(int i=0;i<maxn;i++) Edge[i].clear();

        cin>>m;
        for(int i=0;i<m;i++)
        {
            cin>>str1>>str2;
            if(StrIndex.find(str1)==StrIndex.end()) StrIndex[str1]=n++;
            if(StrIndex.find(str2)==StrIndex.end()) StrIndex[str2]=n++;
            Edge[StrIndex[str1]].push_back(StrIndex[str2]);
            Edge[StrIndex[str2]].push_back(StrIndex[str1]);
        }

        printf("Case #%d: ", ti);
        bool ok=1;
        for(int i=0;i<n;i++){
            if(!dfs(0, 1)) {ok=0; break;}
        }
        puts(ok?"YES":"NO");
    }
	return 0;
}


然后今天写BC第二题,发现还是写不熟练,于是看了JayYe代码,10min就写出来了,太刁
一个技巧,不要全部算完再枚举各种color的个数,而是变量一直更着走,一直计数。cnt[1] cnt[2]

但是边界很恶心,一个是n<=1, 另一个是如果ans=n, 一定是有节的,而且是n-1, 1 所以特盘一下,因为n个离散点了

dfs用bool 类型表示当前dfs(i, c)是否可染色

int n, t, m, ans, u, v;
vector<int> Edge[maxn];
int color[maxn];
int cnt[3];//cnt[0], cnt[1], cnt[2]

bool dfs(int cur, int c){
    color[cur]=c;
    cnt[c]++;
    for(auto i: Edge[cur]){
        if(color[i]){
            if(color[cur]==color[i]) return 0;
        }
        else if(!dfs(i, 3-c)) return 0;
    }
    return 1;
}

int main()
{
/*
#ifndef ONLINE_JUDGE
    freopen ("in.txt" , "r" , stdin);
    freopen ("out.txt" , "w" , stdout);
#endif
*/
    t=getint();
    while(t--){
        n=getint(), m=getint();
        //memset(a, 0 ,sizeof a);//0 means has connectinon
        for(int i=1;i<=n;i++) Edge[i].clear();
        memset(color, 0 ,sizeof color);
        memset(cnt, 0, sizeof cnt);
        for(int i=0;i<m;i++){
            u=getint(), v=getint();
            Edge[u].push_back(v);
            Edge[v].push_back(u);
        }
        bool ok=1;
        int ans=0;
        for(int i=1;i<=n;i++){
            if(color[i]) continue;
            cnt[1]=cnt[2]=0;
            if(!dfs(i, 1)){
                ok=0;
                break;
            }
            ans+=max(cnt[1] , cnt[2]);
        }

        if(ok && n>1){
            if(ans==n) ans--;
            cout<<ans<<" "<<n-ans<<endl;
        }
        else puts("Poor wyh");
    }
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: