【Codeforces Round #589 (Div. 2) D】Complete Tripartite

匿名 (未验证) 提交于 2019-12-03 00:13:02

【链接】 我是链接,点我呀:)
【题意】


题意

【题解】


其实这道题感觉有点狗。
思路大概是这样
先让所有的点都在1集合中。
然后随便选一个点x,访问它的出度y
显然tag[y]=2
因为和他相连了嘛
然后其他没有和x相连的点显然只能和x在同一个集合中
所以其他1集合的点你会发现你想改也没法改,就算他们有可能连在一起也没用,因为你不可能再把其他的1改成2了,因为会和你之前选的A冲突(和这个你想
改的2没有边相连)
这就是这题的主要ideal,就是抓住这一点做文章。
然后接着,我们仍然是随便找一个2号集合里面的点a,遍历它的出度b
显然b只能放在3集合里了。
然后仍然是,你会发现你也不能去动3号集合里的元素了。
就这么锁死了。。。
然后去验证形成的集合是否满足题中给的关系就好。
要记得先判断|set1set2|+|set1set3|+|set2set3|是不是等于m
不然直接暴力判断的话 如果这3个和加起来很大的话(因为你肯定就得这样暴力判断的),会超时的.
(如果等于m的话,你看题中m是比较小的<=3
10^5,所以暴力判断没问题)

【代码】

#include <bits/stdc++.h> using namespace std;  const int N = 1e5;  int n,m; int ans[N+10]; vector<int> h[4]; vector<int> g[N+10]; set<pair<int,int> > myset;  bool ok(int k1,int k2){     int len1 = h[k1].size();     int len2 = h[k2].size();     for (int i = 0;i < len1;i++)         for (int j = 0;j < len2;j++){             int x = h[k1][i],y = h[k2][j];             if (myset.find(make_pair(x,y))==myset.end()) return false;         }     return true; }  int main(){     scanf("%d%d",&n,&m);     for (int i = 1;i <= m;i++){         int x,y;         scanf("%d%d",&x,&y);         g[x].push_back(y);g[y].push_back(x);     }     for (int i = 1;i <= n;i++){         ans[i] = 1;     }     int len = g[1].size();     for (int i = 0;i < len;i++){         int y = g[1][i];         ans[y] = 2;     }     int z = -1;     for (int i = 1;i <= n;i++)         if (ans[i]==2){             z = i;             break;         }     if (z==-1){         printf("-1");         return 0;     }     len = g[z].size();     for (int i = 0;i < len;i++){         int y = g[z][i];         if (ans[y]==2){             ans[y] = 3;         }     }     for (int i = 1;i <= n;i++) h[ans[i]].push_back(i);     if (h[3].empty()) {         printf("-1");         return 0;     }     int n1 = h[1].size(),n2 = h[2].size(),n3 = h[3].size();     if (n1*n2+n1*n3+n2*n3!=m){         printf("-1");         return 0;     }     for (int i = 1;i <= n;i++){         len = g[i].size();         for (int j = 0;j < len;j++){             int y = g[i][j];             myset.insert(make_pair(i,y));         }     }     if (ok(1,2) && ok(1,3) && ok(2,3)){      }else{         printf("-1");         return 0;     }     for (int i = 1;i <= n;i++){         printf("%d\n",ans[i]);     }     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!