zoukankan      html  css  js  c++  java
  • 【ZJOI2017 Round1练习】D2T1 river(二分图)

    题意:

    思路:这道题并没有官方题解

    没有羊驼在所有三元组中出现就是NO

    现在考虑不少于1只的情况

    删去其中一只,我们得到了两组点和一些边

    我们只要判断这是否为一张二分图,使用暴力染色的方法就有60分了

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 10010
     4 #define M 50010
     5 using namespace std;
     6 int T,n,m,edgenum,u,v,ok,isok,root;
     7 int f[N],vet[M],next[M],head[N],a[M],b[M],c[M],vis[N],flag[N],col[N];
     8 void add(int u,int v)
     9 {
    10     vet[++edgenum]=v;
    11     next[edgenum]=head[u];
    12     head[u]=edgenum;
    13 }
    14 void dfs(int u)
    15 {
    16     vis[u]=1;
    17     for (int e=head[u];e;e=next[e])
    18     {
    19         int v=vet[e];
    20         if (flag[v]) continue;
    21         if (vis[v])
    22         {
    23             if (col[v]==col[u]) ok=0;
    24         }else
    25         {
    26             col[v]=col[u]^1;
    27             dfs(v);
    28         }
    29     }
    30 }
    31 int main()
    32 {
    33     freopen("river.in","r",stdin);
    34     freopen("river.out","w",stdout);
    35     scanf("%d",&T);
    36     while (T--)
    37     {
    38         scanf("%d%d",&n,&m);
    39         for (int i=1;i<=n;i++) f[i]=0;
    40         for (int i=1;i<=m;i++)
    41         {
    42             scanf("%d%d%d",&a[i],&b[i],&c[i]);
    43             f[a[i]]++;f[b[i]]++;f[c[i]]++;
    44         }
    45         root=-1;
    46         for (int i=1;i<=n;i++) if (f[i]==m) root=i;
    47         if (root==-1){puts("no");continue;}
    48         edgenum=0;
    49         for (int i=1;i<=n;i++) head[i]=0;
    50         for (int i=1;i<=m;i++)
    51         {
    52             if (a[i]==root){u=b[i];v=c[i];}
    53             if (b[i]==root){u=a[i];v=c[i];}
    54             if (c[i]==root){u=a[i];v=b[i];}
    55             //ed[i].x=u;ed[i].y=v;
    56             add(u,v);add(v,u);
    57         }
    58         isok=0;
    59         //printf("%d
    ",root);
    60         for (int i=1;i<=n;i++) if (i!=root)
    61         {
    62             if (isok) break;
    63             for (int j=i+1;j<=n;j++) if (j!=root)
    64             {
    65                 //printf("%d %d
    ",i,j);
    66                 for (int k=1;k<=n;k++) vis[k]=col[k]=0;
    67                 flag[i]=flag[j]=1;
    68                 ok=1;
    69                 for (int k=1;k<=n;k++) if (!vis[k]&&k!=i&&k!=j&&k!=root)
    70                     dfs(k);
    71                 if (ok) isok=1;
    72                 flag[i]=flag[j]=0;
    73                 if (isok) break;
    74             }
    75         }
    76         if (isok) puts("yes");else puts("no");
    77     }
    78 }

    至于标程……谁看得懂呢……貌似是暴力加了点优化……

     1 #include<bits/stdc++.h>
     2 #define FT first
     3 #define SC second
     4 #define PB push_back
     5 #define MP make_pair
     6 #define REP(i, l, r) for(int i = (l); i <= (r); i++)
     7 #define PER(i, r, l) for(int i = (r); i >= (l); i--)
     8 #define FOR(i, n) for(int i = 0; i < (n); i++)
     9 #define ROF(i, n) for(int i = (n) - 1; i >= 0; i--)
    10 #define VEP(i, x) for(int i = 0; i < x.size(); i++)
    11 #define DFOR(i, x, y) for(int i = hd[x], y = e[i].to; i; i = e[i].nxt, y = e[i].to)
    12 #define MEM(a, b) memset(a, b, sizeof(a))
    13 #define rint read<int>()
    14 #define rll read<LL>()
    15 
    16 using namespace std;
    17 typedef long long LL;
    18 typedef long double LD;
    19 typedef pair<int, int> PI;
    20 const int inf = 0x7fffffff;
    21 const int MOD = 1000000007;
    22 
    23 template <typename tn>
    24 inline tn read(){
    25     char ch; tn f = 1;
    26     while (!isdigit(ch = getchar())) if (ch == '-') f = -1;
    27     tn x = ch - '0';
    28     while (isdigit(ch = getchar())) x = x * 10 + ch - '0';
    29     return x * f;
    30 }
    31 template <typename tn> inline void cmax(tn &a, tn b){ if (a < b) a = b; }
    32 template <typename tn> inline void cmin(tn &a, tn b){ if (a > b) a = b; }
    33 
    34 const int N = 10000 + 5;
    35 struct Edge{ int nxt, to; } e[N * 6];
    36 struct Data{ int f, safe, danger; };
    37 int color[N], x[N], y[N], z[N], sz[N], rt, tail, hd[N], tot, dep[N], S, T;
    38 void add(int x, int y){ e[++tail] = (Edge){hd[x], y}, hd[x] = tail; }
    39 Data dfs(int x, int c, int f){
    40     color[x] = c;
    41     Data cur;
    42     cur.safe = inf, cur.danger = -1, cur.f = 0;
    43     DFOR(i, x, y) if (y != f && color[y] != -2)
    44         if (!~color[y]){
    45             dep[y] = dep[x] + 1;
    46             Data now = dfs(y, c ^ 1, x); 
    47             cur.f += now.f;    if (cur.f > 1) { return cur;}
    48             cmin(cur.safe, now.safe), cmax(cur.danger, now.danger);
    49         } else if (dep[y] < dep[x]) if (color[x] ^ color[y]) cmin(cur.safe, dep[y]); else{
    50             cmax(cur.danger, dep[y]);
    51             if (!S) S = x, T = y;
    52             if (S != x && S != y) S = -1;
    53             if (T != x && T != y) T = -1;
    54         }
    55     if (cur.safe <= dep[x] && cur.danger >= dep[x]) cur.f = 100;
    56     else if (cur.danger >= dep[x]) cur.f++, cur.danger = -1;
    57     return cur;
    58 }
    59 int main(){
    60     freopen("river.in", "r", stdin);
    61     freopen("river.out", "w", stdout);
    62     int Cas = rint;
    63     while (Cas--){
    64         int n = rint, m = rint;
    65         MEM(sz, 0), MEM(hd, 0), tail = 0, rt = 0;
    66         REP(i, 1, m) sz[x[i] = rint]++, sz[y[i] = rint]++, sz[z[i] = rint]++;
    67         REP(i, 1, n) if (sz[i] == m) rt = i;
    68         if (rt){
    69             bool ans = 0;
    70             REP(i, 1, m){
    71                 if (x[i] == rt) swap(x[i], z[i]);
    72                 if (y[i] == rt) swap(y[i], z[i]);
    73                 add(x[i], y[i]), add(y[i], x[i]);
    74             } 
    75             REP(i, 1, n) if (i != rt) { 
    76                 MEM(color, -1), color[i] = -2;
    77                 int flag = 1, tot = 0;
    78                 REP(i, 1, n) if (color[i] == -1){
    79                     S = 0, T = 0;
    80                     int tmp = dfs(i, 0, 0).f;
    81                     if (S > 0 || T > 0) cmin(tmp, 1);
    82                     tot += tmp;
    83                     if (tot > 1) {flag = 0; break;}
    84                 }
    85                 if (flag) {ans = 1; break;}
    86             }
    87             if (ans) printf("yes
    "); else printf("no
    ");
    88         } else printf("no
    ");
    89     }
    90 }
  • 相关阅读:
    自定义类型百度地图之自定义地图类型详解
    电话文本android(3)_拨打电话操作
    检查运行IIS 5.1 使用出现server application error解决方法
    function运行令人吐血的IE JS兼容性问题。。。
    组件设置window2008 64位系统无法调用Microsoft.Office.Interop组件进行文件另存的解决办法
    api时间转换VarDateFromStr,VariantTimeToSystemTime
    C与CPP文件的区别
    OpenSSL 使用指南
    Pascal保留字/关键字列表
    windbg 启动参数,常用命令
  • 原文地址:https://www.cnblogs.com/myx12345/p/6488924.html
Copyright © 2011-2022 走看看