zoukankan      html  css  js  c++  java
  • Codeforces Round #589 (Div. 2) D. Complete Tripartite

    题目地址:https://codeforces.com/contest/1228/problem/D

    题意:给你n个点,m条边,能否构成三分图,每条边都要用上

    思路:分三个集合f1、f2、f3,与f1、f2相连但与f3不相连的,与f2、f3相连但与f1不相连的,与f1、f3相连但与f2不相连的。三分图的原因,可以直接取点1作为集合一的一个点a1,再取与1相连的第一个点作为第二个集合的点a2,接着找到与点一点二都相连的点a3。然后就是遍历所有的点,分类到三个集合中去,检测所得的三分图的边是否与m相同和每个集合里的边是否有相连的即可。

    AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 using namespace std;
     7 typedef long long ll;
     8 const int MAXN=1e5+5;
     9 int n,m;
    10 vector<int>a[MAXN];
    11 void sol(){
    12     if(a[1].size()==0){
    13         cout<<"-1";
    14         return ;
    15     }
    16     int f1=1,f2=0,f3=0;
    17     int color[MAXN];
    18     memset(color,0,sizeof(color));
    19     f2=a[f1][0];
    20     color[1]=1;
    21     color[a[f1][0]]=2;
    22     for(int j=1;j<=n;j++){     //找到f2和f3
    23         bool a1=false,a2=false;
    24         for(int i=0;i<a[j].size();i++){
    25             if(a[j][i]==f1) a1=true;
    26             if(a[j][i]==f2) a2=true;
    27         }
    28         if(a1&&a2){
    29             f3=j;
    30             break;
    31         }
    32     }
    33     if(!f3){      //若没有f3则直接输出-1
    34         cout<<"-1";
    35         return ;
    36     }
    37     color[f3]=3;
    38     for(int i=1;i<=n;i++){   //分到各个集合里
    39         int a1=0,a2=0,a3=0;
    40         for(int j=0;j<a[i].size();j++){   //检测i点与f1,f2,f3那些点相连
    41             if(a[i][j]==f1) a1=1;
    42             if(a[i][j]==f2) a2=1;
    43             if(a[i][j]==f3) a3=1;
    44         }
    45         if(a1+a2+a3!=2){    //若不是与其中两个点相连则直接输出-1
    46             cout<<"-1";
    47             return ;
    48         }
    49         if(a1&&a2&&!a3) color[i]=3;
    50         if(a1&&!a2&&a3) color[i]=2;
    51         if(!a1&&a2&&a3) color[i]=1;
    52     }
    53     int cnt[4]={0};
    54     for(int i=1;i<=n;i++) cnt[color[i]]++;      
    55     if(cnt[1]*cnt[2]+cnt[2]*cnt[3]+cnt[3]*cnt[1]!=m){       //计算边的数量是否为m
    56         cout<<"-1";
    57         return ;
    58     }
    59     for(int i=1;i<=n;i++){       //回路判断,检查每个集合里是否有相连的
    60         for(int j=0;j<a[i].size();j++){
    61             if(color[i]==color[a[i][j]]){
    62                 cout<<"-1";
    63                 return ;
    64             }
    65         }
    66     }
    67     for(int i=1;i<=n;i++)
    68         cout<<color[i]<<" ";
    69 }
    70 int main(){
    71     cin>>n>>m;
    72     int x,y;
    73     for(int i=0;i<m;i++){
    74         cin>>x>>y;
    75         a[x].push_back(y);
    76         a[y].push_back(x);
    77     }
    78     sol();
    79     return 0;
    80 }

    其中检测边的步骤,我试过去检测每个点是否都用上了,但WA了,有点懵。

  • 相关阅读:
    1.8 Hello World添加menu
    1.7 HelloWorld 添加视图
    1.6 Hello World
    1.5 组件开发基础
    awk
    sed
    grep / egrep
    Shell基础知识
    和管道符有关的命令
    Shell变量
  • 原文地址:https://www.cnblogs.com/xunzf0402/p/11679911.html
Copyright © 2011-2022 走看看