zoukankan      html  css  js  c++  java
  • bzoj1143[CTSC2008] 祭祀river

    题目链接:bzoj1143

    题目大意:

    n个点m条有向边(保证无环)。要求选最多的点,使该点集中每个点都不能到达点集中的其他点。


    题解:

    最长反链

    我觉得能想到匈牙利好厉害啊。根本不会往哪方面想。。。
    因为有个背景知识...最长反链与最小链覆盖
    大概可以看看这个http://vfleaking.blog.163.com/blog/static/1748076342012918105514527/
    所以这道题就是裸的求最长反链=最小链覆盖。而求最小链覆盖数的方法就是首先传递闭包,然后就变成了最小路径覆盖。拆点,用二分图匹配解决。
    因为n<=100很小,所以直接floyd搞就好了。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 110
    
    bool bo[maxn][maxn];
    int n,ask[maxn],bf[maxn],tim;
    int ffind(int x)
    {
    	for (int i=1;i<=n;i++)
    	 if (bo[x][i] && ask[i]!=tim)
     	 {
    		ask[i]=tim;
    		if (bf[i]==-1 || ffind(bf[i]))
    		{
    			bf[i]=x;
    			return true;
    		}
    	 }
    	return false;
    }
    int main()
    {
    	//freopen("a.in","r",stdin);
    	//freopen("a.out","w",stdout);
    	int m,i,j,k,x,y,sum,ans;
    	scanf("%d%d",&n,&m);
    	memset(bo,false,sizeof(bo));
    	for (i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		bo[x][y]=true;
    	}
    	for (k=1;k<=n;k++) 
    	 for (i=1;i<=n;i++)
    	  for (j=1;j<=n;j++) if (i!=j)
    	   if (i!=k && j!=k)
    		if (bo[i][k] && bo[k][j]) bo[i][j]=true;
    	ans=tim=0;
    	memset(ask,0,sizeof(ask));
    	memset(bf,-1,sizeof(bf));
    	for (i=1;i<=n;i++)
    	{
    		tim++;
    		if (ffind(i)) ans++;
    	}
    	ans=n-ans;
    	printf("%d
    ",ans);
    	return 0;
    }


  • 相关阅读:
    建设是为“有” 共享是为“无”
    设计模式-命令模式
    设计模式-建造者模式
    设计模式-抽象工厂模式(升级版工厂方法模式)
    设计模式-原型模式
    设计模式-单例模式
    Java中的多维数组
    设计模式-装饰者
    设计模式-模板方法
    乐观锁与悲观锁
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527802.html
Copyright © 2011-2022 走看看