[bzoj1143]祭祀

Posted pywbktda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj1143]祭祀相关的知识,希望对你有一定的参考价值。

求最长反链(链上任意两个点不连通),可以发现,最长反链=最小链覆盖(因为每一条链都最多只有一个点入选),而DAG的最小链覆盖也就是最小路径覆盖(可相交)。然后floyd传递闭包,将任意两个连通的点都连一条边,这样就变成不可相交的最小路径覆盖(可以绕过去)。

不可相交的最小路径覆盖:将每一个点裂成两个点,分别处理出边和入边,形成二分图,二分图上的每一个匹配意味着答案-1,因此n-最大匹配数。

技术图片
 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

 

以上是关于[bzoj1143]祭祀的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1143[CTSC2008]祭祀river

bzoj 1143: [CTSC2008]祭祀river

[bzoj1143]祭祀

[BZOJ1143]祭祀

bzoj1143: [CTSC2008]祭祀river 最长反链

bzoj1143: [CTSC2008]祭祀river