• ZOJ 1015 弦图判定


    一些定义:

    弦图是一种特殊图:它的所有极小环都只有3个顶点。

    单纯点:该顶点与其邻接点在原图中的导出子图是一个完全图。

    图G的完美消去序列:一个顶点序列a1a2a3...an,使得对于每个元素ai,ai在ai、ai+1、ai+2...an的导出子图中是一个单纯点。

    弦图有一个性质:任何一个弦图都至少存在一个单纯点(该点和其邻接点组成一个完全图)

    弦图另一个性质:一个图是弦图当且仅当其存在完美消去序列。(归纳证明)

    最大势算法(msc):若原图是弦图,则该算法计算出的序列是完美消去序列。

    算法大致思想:从后往前计算序列,每次选择点v作为序列中的元素,v是还未选的点中与已经选了的点连边最多的点。

    然后检查该序列是否是完美消去序列。

    请看陈丹琦的ppt:《弦图与区间图》

    BZOJ:

     1 /**************************************************************
     2     Problem: 1242
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:544 ms
     7     Memory:1816 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #define N 1010
    13 #define M N*N*2
    14  
    15 int n, m;
    16 bool c[N][N];
    17 int qu[N], inq[N], dgr[N];
    18 int stk[N], top;
    19  
    20 void msc() {
    21     dgr[0] = -1;
    22     for( int i=n; i>=1; i-- ) {
    23         int s = 0;
    24         for( int u=1; u<=n; u++ ) 
    25             if( !inq[u] && dgr[u]>dgr[s] ) s=u;
    26         qu[i] = s;
    27         inq[s] = true;
    28         for( int u=1; u<=n; u++ )
    29             if( !inq[u] && c[s][u] ) dgr[u]++;
    30     }
    31 }
    32 bool check() {
    33     for( int i=n; i>=1; i-- ) {
    34         int s=qu[i];
    35         top = 0;
    36         for( int j=i+1; j<=n; j++ )
    37             if( c[s][qu[j]] ) stk[++top] = qu[j];
    38         if( top==0 ) continue;
    39         for( int j=2; j<=top; j++ )
    40             if( !c[stk[1]][stk[j]] ) return false;
    41     }
    42     return true;
    43 }
    44 int main() {
    45     scanf( "%d%d", &n, &m );
    46     for( int i=1,u,v; i<=m; i++ ) {
    47         scanf( "%d%d", &u, &v );
    48         c[u][v] = c[v][u] = 1;
    49     }
    50     msc();
    51     printf( "%s
    ", check() ? "Perfect" : "Imperfect" );
    52 }
    53 
    View Code

     ZOJ:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #include <vector>
     5 #define maxn 1010
     6 using namespace std;
     7 
     8 int n, m;
     9 vector<int> g[maxn];
    10 bool connect[maxn][maxn];
    11 
    12 int id[maxn];
    13 int label[maxn];
    14 int seq[maxn];
    15 
    16 struct Stat {
    17     int lab, u;
    18     Stat( int lab, int u ) : lab(lab), u(u) {}
    19     bool operator<( const Stat & b ) const { 
    20         return lab<b.lab;
    21     }
    22 };
    23 void mcs() {
    24     priority_queue<Stat> pq;
    25     memset( label, 0, sizeof(label) );
    26     memset( id, 0, sizeof(id) );
    27     for( int u=1; u<=n; u++ ) pq.push(Stat(0,u));
    28 
    29     for( int i=n; i>=1; i-- ) {
    30         while( id[pq.top().u] ) pq.pop();
    31         int u = pq.top().u;
    32         pq.pop();
    33         id[u] = i;
    34         for( int t=0; t<g[u].size(); t++ ) {
    35             int v = g[u][t];
    36             if( !id[v] ) {
    37                 label[v]++;
    38                 pq.push( Stat(label[v],v) );
    39             }
    40         }
    41     }
    42     for( int u=1; u<=n; u++ ) 
    43         seq[id[u]] = u;
    44 }
    45 
    46 bool check() {
    47     vector<int> c;
    48     for( int i=1; i<=n; i++ ) {
    49         int u = seq[i];
    50         c.clear();
    51         for( int t=0; t<g[u].size(); t++ ) {
    52             int v = g[u][t];
    53             if( id[v]>id[u] ) 
    54                 c.push_back(v);
    55         }
    56         if( c.empty() ) continue;
    57         int sc = c[0];
    58         for( int t=1; t<c.size(); t++ ) 
    59             if( id[c[t]]<id[sc] ) sc=c[t];
    60         for( int t=0; t<c.size(); t++ ) {
    61             int v = c[t];
    62             if( v==sc ) continue;
    63             if( !connect[sc][v] ) return false;
    64         }
    65     }
    66     return true;
    67 }
    68 void init( int n ) {
    69     memset( connect, false, sizeof(connect) );
    70     for( int u=1; u<=n; u++ ) g[u].clear();
    71 }
    72 int main() {
    73     while(1) {
    74         scanf( "%d%d", &n, &m );
    75         if( n==0 && m==0 ) return 0;
    76         init(n);
    77         for( int i=1,u,v; i<=m; i++ ) {
    78             scanf( "%d%d", &u, &v );
    79             connect[u][v] = connect[v][u] = true;
    80             g[u].push_back(v);
    81             g[v].push_back(u);
    82         }
    83         mcs();
    84         printf( "%s
    
    ", check() ? "Perfect" : "Imperfect" );
    85     }
    86 }
    View Code

     暴力:每次找单纯点,删掉,再找,如果能删完就说明是.

    O(n^4*...)

     1 #include <cstdio>
     2 #include <vector>
     3 #include <set>
     4 #define N 110
     5 #define foreach(it,s) for( typeof(s.begin()) it=s.begin(); it!=s.end(); it++ )
     6 using namespace std;
     7 
     8 int n, m;
     9 set<int> s;
    10 set<int> g[N];
    11 
    12 bool find_erase() {
    13     foreach( u, s ) {
    14         vector<int> vc;
    15         foreach( v, g[*u] ) 
    16             vc.push_back(*v);
    17         bool ok = true;
    18         for( int a=0; a<vc.size() && ok; a++ ) 
    19             for( int b=a+1; b<vc.size() && ok; b++ )
    20                 if( g[vc[a]].count(vc[b])==0 ) 
    21                     ok = false;
    22         if( ok ) {
    23             s.erase(*u);
    24             for( int t=0; t<g[*u].size(); t++ )
    25                 g[vc[t]].erase(*u);
    26             return true;
    27         }
    28     }
    29     return false;
    30 }
    31 int main() {
    32     scanf( "%d%d", &n, &m );
    33     for( int i=1; i<=n; i++ )
    34         s.insert(i);
    35     for( int i=1,u,v; i<=m; i++ ) {
    36         scanf( "%d%d", &u, &v );
    37         if( g[u].count(v) ) continue;
    38         g[u].insert(v);
    39         g[v].insert(u);
    40     }
    41     for( int t=1; t<=n; t++ ) {
    42         if( !find_erase() ) {
    43             printf( "Imperfect
    " );
    44             return 0;
    45         }
    46     }
    47     printf( "Perfect
    " );
    48 }
    View Code
  • 相关阅读:
    记一下后续要看的点
    vue 封装request.js
    shuf命令简单用法
    Redis string 字符串
    Redis 事务操作
    Redis Zset 有序集合
    php操作redis的一些基本操作
    pytest自动化测试入门介绍
    idea&myeclipse 自动生成serialVersionUID
    leetCode1104. 二叉树寻路(medium)
  • 原文地址:https://www.cnblogs.com/idy002/p/4295392.html
Copyright © 2020-2023  润新知