zoukankan      html  css  js  c++  java
  • poj2942Knights of the Round Table

    http://poj.org/problem?id=2942

    代码敲的迷迷糊糊的 照把书上的给搬上来的

    给篇讲的不错的解题报告 各种定义都有 http://blog.csdn.net/lyy289065406/article/details/6756821

    做这题之前 一定要把相关定义搞清楚 割点 双连通分量  二分图  奇圈

    View Code
      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<stack>
      7 #include<vector>
      8 using namespace std;
      9 struct node
     10 {
     11     int u,v;
     12 };
     13 vector<int>G[1010],bcc[1010];
     14 int w[1010][1010],pre[1010],iscut[1010],bccno[1010],dc,bc,odd[1010],co[1010];
     15 stack<node>s;
     16 int dfs(int u,int fa)
     17 {
     18     int lowu  = pre[u]= ++dc;
     19     int child  =0,i;
     20     for(i = 0 ; i < G[u].size() ; i++)
     21     {
     22         int v = G[u][i];
     23         node e = (node){u,v};
     24         if(!pre[v])
     25         {
     26             s.push(e);
     27             child++;
     28             int lowv = dfs(v,u);
     29             lowu = min(lowv,lowu);
     30             if(lowv>=pre[u])
     31             {
     32                 bc++;
     33                 bcc[bc].clear();//将找到的双连通分量依次 存起来
     34                 iscut[u] = 1;
     35                 for(;;)
     36                 {
     37                     node x = s.top();
     38                     s.pop();
     39                     if(bccno[x.u]!=bc)
     40                     {
     41                         bcc[bc].push_back(x.u);
     42                         bccno[x.u] = bc;
     43                     }
     44                     if(bccno[x.v]!=bc)
     45                     {
     46                         bcc[bc].push_back(x.v);
     47                         bccno[x.v] = bc;
     48                     }
     49                     if(x.u==u&&x.v==v)
     50                         break;
     51                 }
     52             }
     53         }
     54         else if(pre[v]<pre[u]&&v!=fa)
     55         {
     56             s.push(e);
     57             lowu = min(lowu,pre[v]);
     58         }
     59     }
     60     if(fa<0&&child==1)
     61         iscut[u] = 0;//其实没看出来iscut有嘛用。。
     62     return lowu;
     63 }
     64 void find_bcc(int n)//找双连通分量
     65 {
     66     memset(pre,0,sizeof(pre));
     67     memset(iscut,0,sizeof(iscut));
     68     memset(bccno,0,sizeof(bccno));
     69     dc = bc = 0;
     70     for(int i = 1 ; i <= n ; i++)
     71         if(!pre[i])
     72             dfs(i,-1);
     73 }
     74 int bipart(int u,int b)//判断是不是二分图 着色法
     75 {
     76     int i;
     77     for(i = 0 ; i < G[u].size() ; i++)
     78     {
     79         int v = G[u][i];
     80         if(bccno[v]!=b) continue;
     81         if(co[v] == co[u])
     82         return 0;
     83         if(!co[v])
     84         {
     85             co[v] = 3-co[u];
     86             if(!bipart(v,b))
     87             return 0;
     88         }
     89     }
     90     return 1;
     91 }
     92 int main()
     93 {
     94     int i,j,k,n,m,g;
     95     while(cin>>n>>m)
     96     {
     97         if(n==0&&m==0)
     98             break;
     99         for(i = 1; i <= n ; i++)
    100             G[i].clear();
    101         memset(w,0,sizeof(w));
    102         for(i = 1 ; i <= m ;i++)
    103         {
    104             int u,v;
    105             scanf("%d%d",&u,&v);
    106             w[u][v] = 1;
    107             w[v][u] = 1;
    108         }
    109         for(i = 1; i <= n ; i++)
    110             for(j = i+1 ; j <= n ; j++)
    111                 if(!w[i][j])
    112                 {
    113                     G[i].push_back(j);
    114                     G[j].push_back(i);
    115                 }
    116         find_bcc(n);
    117         memset(odd,0,sizeof(odd));
    118         for(i = 1 ; i <= bc ; i++)
    119         {
    120             memset(co,0,sizeof(co));
    121             for(j = 0 ; j < bcc[i].size() ; j++)
    122             bccno[bcc[i][j]] = i;//双连通分量的割顶
    123             int u = bcc[i][0];
    124             co[u] = 1;
    125             if(!bipart(u,i))
    126             {
    127                 for(g =  0 ; g < bcc[i].size() ;g++)
    128                 odd[bcc[i][g]] = 1;
    129             }
    130         }
    131         int ans = 0;
    132         for(i = 1 ; i <= n ; i++)//不在奇圈中的计数
    133             if(!odd[i])
    134             ans++;
    135         cout<<ans<<endl;
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    IE下判断IE版本的语句...[if lte IE 6]……[endif]
    “浏览器模式”和“文档模式”
    IoC框架---通俗概述
    Castle IOC容器组件生命周期管理
    Castle学习笔记----初探IOC容器
    Castle IOC容器内幕故事(下)
    Castle IOC容器内幕故事(上)
    Castle IOC容器构建配置详解(二)
    javascript属性一览
    javascript addEventListener方法
  • 原文地址:https://www.cnblogs.com/shangyu/p/3024672.html
Copyright © 2011-2022 走看看