Codeforces Round #167 (Div. 1) - C. Dima and Horses
算法提示
贪心、BFS
题目大意
有 n 匹马,每匹马都有不超过 3 个敌人,要求把这些马分成两部分(允许一部分中没有一条马),使得对于每条马,和它在同一部分中的敌人的数量不超过1个给出了所有的敌对关系,求一个划分的方案。如果不存在划分方案,输出 -1 。
做法分析
首先题目指出,每匹马的敌人不超过 3 个,也就是说对于某匹马来说,在当前部分不合法,那么在另一部分必然是合法的。对于 4 匹马,每匹马 3 个敌人的完全图来说,是有解的,那么对于 n 匹马的稀疏图,也能够找到一种合法方案。
我们假设所有马在同一个部分,我们选择不合法的马,把它放到另一个部分去,再选择不合法的马,如此循环,直到所有马都合法。
参考代码
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <queue> 5 #include <algorithm> 6 7 using namespace std; 8 9 #define MAXN 300010 10 #define INF 0x3f3f3f3f 11 #define MAX(a,b) (a>b?a:b) 12 #define MIN(a,b) (a<b?a:b) 13 #define ABS(m) (m<0?-m:m) 14 #define mo 1000000007 15 typedef long long LL; 16 17 int n,m,vis[MAXN]; 18 19 struct node 20 { 21 int v; 22 node *next; 23 }edge[MAXN*2]; 24 node *cnt=&edge[0]; 25 node *adj[MAXN]; 26 27 void Addedge(int u,int v) 28 { 29 node *p=++cnt; 30 p->v=v; 31 p->next=adj[u]; adj[u]=p; 32 } 33 34 void Init() 35 { 36 int i,u,v; 37 scanf("%d%d",&n,&m); 38 for(i=1;i<=m;++i){ 39 scanf("%d%d",&u,&v); 40 Addedge(u,v); 41 Addedge(v,u); 42 } 43 } 44 45 void Work() 46 { 47 int i,u,cnt; 48 queue<int> q; 49 for(i=1;cnt=0,i<=n;++i){ 50 for(node *p=adj[i];p;p=p->next) 51 cnt+=(vis[p->v]==vis[i]); 52 if(cnt>1) q.push(i); 53 } 54 while(!q.empty()){ 55 u=q.front(); q.pop(); cnt=0; 56 for(node *p=adj[u];p;p=p->next) 57 cnt+=(vis[p->v]==vis[u]); 58 if(cnt>1){ 59 vis[u]^=1; 60 for(node *p=adj[u];cnt=0,p;p=p->next){ 61 for(node *pp=adj[p->v];pp;pp=pp->next) 62 cnt+=(vis[pp->v]==vis[p->v]); 63 if(cnt>1) q.push(p->v); 64 } 65 } 66 } 67 for(i=1;i<=n;++i) printf("%d",vis[i]); 68 } 69 70 int main() 71 { 72 Init(); 73 Work(); 74 return 0; 75 }
题目链接
Codeforces Round #167 (Div. 1) - C. Dima and Horses

浙公网安备 33010602011771号