CH6902 Vani and Cl2 hide and seek

description

Vani and cl2 hide and seek in the midst of the woods. N these woods have a house, there are M stripe to the road, constitute a directed acyclic graph. N≤200, M≤30000.
Woods tree very dense enough to block the view, but looked along the road, but it is visibility. If you can reach B from A house along the road to go, then the people in A and B in to be able to saw each other.
Between any two cl2 are now to be selected in this house, Block N, Block K as a hiding spot, but also a rarity in cl2 Vani as a hiding spot inside the house looking for, in order to avoid being seen Vani, cl2 requirements of the K point of hiding the path is not connected.
To make it harder to find their own Vani, cl2 want to know the maximum number of points can elect to hide.

Input Format

The first line of input data are two integers N and M. Next M rows, each row two integers x, y, represents a directed path from x to y.

Output Format

Output an integer K, represents the number of hiding up to the selected point.

In the second line of the output of the K space-separated integers, indicates hiding the selected point number. If there are multiple schemes, any one can be output. Output number any order.

Sample input

7 5
1 2
3 2
2 4
4 5
4 6

Sample Output

3
1 3 7

Data range and Conventions

  • For 20% of the data, N≤10, M <= 20.
    For 60% of the data, N≤100, M <= 1000.
    To 100% of the data, N≤200, M <= 30000,1 < = x, y <= N.

The title checker (SPJ)

01 #include <iostream>
02 #include <cstdio>
03 #include <cstring>
04 #include <algorithm>
05 #include <vector>
06 using namespace std;
07 //一些定义
08 const int ACCEPT = 0;
09 const int WRONG_ANSWER = 1;
10 //fstd 标准输出 fout 选手输出 fin 标准输入
11 FILE *fstd,*fout,*fin;
12 int n, m, ans, val;
13 bool v[210], f[210];
14 vector<int> ver[210];
15  
16 bool dfs(int x) {
17     f[x] = 1;
18     if (v[x]) return true;
19     for (int i = 0; i < ver[x].size(); i++) {
20         int y = ver[x][i];
21         if (f[y]) continue;
22         if (dfs(y)) return true;
23     }
24     return false;
25 }
26  
27 //执行比较操作。
28 bool DoCompare(){
29     fscanf(fin, "%d%d", &n, &m);
30     for (int i = 1; i <= m; i++) {
31         int x, y;
32         fscanf(fin, "%d%d", &x, &y);
33         ver[x].push_back(y);
34     }
35     fscanf(fstd, "%d", &ans);
36     fscanf(fout, "%d", &val);
37     // 答案不对
38     if (val != ans) return false;
39     for (int i = 1; i <= ans; i++) {
40         int x; fscanf(fout, "%d", &x);
41         // 输出的藏身点不合法或有重复
42         if (x < 1 || x > n || v[x]) return false;
43         v[x] = 1;
44     }
45     for (int i = 1; i <= n; i++) {
46         if (!v[i]) continue;
47         memset(f, 0, sizeof(f));
48         v[i] = 0;
49         // 能看到别的点
50         if (dfs(i)) return false;
51         v[i] = 1;
52     }
53     return true;
54 }
55  
56 int main(int argc, char* argv[])
57 {
58     if(argc!=4){
59         printf("参数不足 %d",argc);
60         return -1;
61     }
62  
63     //打开文件
64     if(NULL==(fstd=fopen(argv[1],"r"))){
65         return -1;
66     }
67     if(NULL==(fout=fopen(argv[2],"r"))){
68         return -1;
69     }
70     if(NULL==(fin=fopen(argv[3],"r"))){
71         return -1;
72     }
73  
74     if(DoCompare()){
75         return ACCEPT;
76     }else{
77         return WRONG_ANSWER;
78     }
79 }

answer

Hiding the minimum number of points equal to the number of paths may be repeated point coverage paths included. Simply transitive closure, split point run bipartite graph maximum matching, it subtracts the number of points of the line.

See proof "Advanced", it is a reductio ad absurdum of the use of the structure.

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;

co int N=201;
bool cl[N][N];
int match[N],n,m;
bool vis[N],succ[N];
int hide[N];

bool dfs(int x){
    for(int i=1;i<=n;++i)
        if(cl[x][i]&&!vis[i]){
            vis[i]=1;
            if(!match[i]||dfs(match[i])){
                match[i]=x;
                return 1;
            }
        }
    return 0;
}
int main(){
    read(n),read(m);
    while(m--) cl[read<int>()][read<int>()]=1;
    for(int i=1;i<=n;++i) cl[i][i]=1;
    for(int k=1;k<=n;++k)
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                cl[i][j]|=cl[i][k]&cl[k][j];
    for(int i=1;i<=n;++i) cl[i][i]=0;
    // Maximum Matching on Split Bipartite Graph
    int ans=n;
    for(int i=1;i<=n;++i){
        memset(vis,0,sizeof vis);
        ans-=dfs(i);
    }
    printf("%d\n",ans);
    for(int i=1;i<=n;++i) succ[match[i]]=1;
    for(int i=1,k=0;i<=n;++i)
        if(!succ[i]) hide[++k]=i;
    memset(vis,0,sizeof vis);
    for(bool modify=1;modify;){
        modify=0;
        for(int i=1;i<=ans;++i)
            for(int j=1;j<=n;++j)
                if(cl[hide[i]][j]) vis[j]=1;
        for(int i=1;i<=ans;++i)
            if(vis[hide[i]]){
                modify=1;
                while(vis[hide[i]]) hide[i]=match[hide[i]];
            }
    }
    for(int i=1;i<=ans;++i) printf("%d ",hide[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/autoint/p/10978966.html