[Bzoj1143] worship

Longest seek anti-chain (the chain at any two points do not communicate), can be found, the longest chain trans = minimum chain cover (because each strand have at most one point selected), and DAG minimum chain is covered by the smallest path covering (may intersect). Then floyd transitive closure, any two points are connected a communication side, this becomes a minimum path not intersecting cover (can go around).

Minimum path not intersecting coverage: each of points fragmented into two points, respectively, a side and into the process side, forming a bipartite graph, each matching answer means that the bipartite graph -1 , and therefore is n- maximum number of matches.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 205
 4 struct ji{
 5     int nex,to;
 6 }edge[N*N];
 7 int E,n,m,x,y,ans,head[N],vis[N],flag[N],f[N][N];
 8 void add(int x,int y){
 9     edge[E].nex=head[x];
10     edge[E].to=y;
11     head[x]=E++;
12 }
13 bool dfs(int k){
14     if (vis[k])return 0;
15     vis[k]=1;
16     for(int i=head[k];i!=-1;i=edge[i].nex){
17         int v=edge[i].to;
18         if ((!flag[v])||(dfs(flag[v]))){
19             flag[k]=v;
20             flag[v]=k;
21             return 1;
22         }
23     }
24     return 0;
25 }
26 int main(){
27     scanf("%d%d",&n,&m);
28     memset(head,-1,sizeof(head));
29     for(int i=1;i<=m;i++){
30         scanf("%d%d",&x,&y);
31         f[x][y]=1;
32     }
33     for(int i=1;i<=n;i++)
34         for(int j=1;j<=n;j++)
35             for(int k=1;k<=n;k++)
36                 f[j][k]|=((f[j][i])&(f[i][k]));
37     for(int i=1;i<=n;i++)
38         for(int j=1;j<=n;j++)
39             if (f[i][j])add(i,j+n);
40     ans=n;
41     for(int i=1;i<=n;i++){
42         memset(vis,0,sizeof(vis));
43         if (!flag[i])ans-=dfs(i);
44     }
45     printf("%d",ans);
46 }
View Code

 

Guess you like

Origin www.cnblogs.com/PYWBKTDA/p/11247987.html