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)
09 |
const int WRONG_ANSWER = 1; |
11 |
FILE *fstd,*fout,*fin; |
18 |
if (v[x]) return true ; |
19 |
for ( int i = 0; i < ver[x].size(); i++) { |
22 |
if (dfs(y)) return true ; |
29 |
fscanf (fin, "%d%d" , &n, &m); |
30 |
for ( int i = 1; i <= m; i++) { |
32 |
fscanf (fin, "%d%d" , &x, &y); |
35 |
fscanf (fstd, "%d" , &ans); |
36 |
fscanf (fout, "%d" , &val); |
38 |
if (val != ans) return false ; |
39 |
for ( int i = 1; i <= ans; i++) { |
40 |
int x; fscanf (fout, "%d" , &x); |
42 |
if (x < 1 || x > n || v[x]) return false ; |
45 |
for ( int i = 1; i <= n; i++) { |
47 |
memset (f, 0, sizeof (f)); |
50 |
if (dfs(i)) return false ; |
56 |
int main( int argc, char * argv[]) |
59 |
printf ( "参数不足 %d" ,argc); |
64 |
if (NULL==(fstd= fopen (argv[1], "r" ))){ |
67 |
if (NULL==(fout= fopen (argv[2], "r" ))){ |
70 |
if (NULL==(fin= fopen (argv[3], "r" ))){ |
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;
}