• 题解 P1330 【封锁阳光大学】


    安利一波自己的博客

    看到题解中各位大佬都是用的黑白染色,蒟蒻表示不才,于是写了一发树形dp过了此题。


    思路:

    首先,我们如果把这个图当做树来看的话,那么它有可能不止一棵树,所以它有可能是森林。我们可以用并查集来维护每一个连通块,设 (root[i]) 表示连通块 (i) 的根节点是哪一个,注意,最开始没有连边的时候,每一个连通块的根都是他自己。

    解决完了遍历的问题后,我们设 (f[i][0/1]) 表示在以i为根的子树上选/不选这个点所需的最少的河蟹数量,则得出转移方程:
    (f[i][0]=sum_{vin son[i]}f[v][1])
    (f[i][1]=sum_{vin son[i]}f[v][0] +1)

    然后我们将每一个联通块跑一遍树形 (dp),再将答案累加每一个根放还是不放的最大值,最后输出答案即可。
    最后需要注意的一个点,如果 (mgeq n) 或者遍历的时候遇到了已经访问过的点,那么说明这张图有回路,不可能存在合法答案,输出 (Impossible)
    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    struct Node
    {
    	int t;
    	int next;
    }node[200011];
    bool book[10011];
    int root[10011],f[10011];
    int head[10011],tot=0,dp[10011][2];
    int n,m;
    void init()
    {
    	for(int i=1;i<=n;++i)
    		f[i]=i,root[i]=i;
    }
    int getf(int v)
    {
    	if(f[v]==v) return v;
    	else return f[v]=getf(f[v]);
    }
    void merge(int a,int b)
    {
    	int t1=getf(a),t2=getf(b);
    	if(t1!=t2) f[t2]=t1,root[t2]=root[t1];
    }
    void add(int x,int y)
    {
    	node[++tot].t=y;
    	node[tot].next=head[x];
    	head[x]=tot;
    }
    void dfs(int f,int fa)
    {
    	if(book[f]) 
    	{
    		cout<<"Impossible";
    		exit(0);
    	}
    	book[f]=1;
    	dp[f][1]=1;
    	bool flag=0;
    	for(int i=head[f];i;i=node[i].next)
    	{
    		int u=node[i].t;
    		if(u==fa) continue;
    		dfs(u,f);
    		dp[f][0]+=dp[u][1];
    		dp[f][1]+=dp[u][0];
    	}
    }
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);	
    	int ans=0;
    	scanf("%d %d",&n,&m); 
    	init(); 
    	for(int i=1;i<=m;++i) 
    	{
    		int x,y;
    		scanf("%d %d",&x,&y);
    		merge(x,y);
    		add(x,y);
    		add(y,x);
    	}
    	if(m>=n)
    		cout<<"Impossible";
    	else
    	{
    		for(int i=1;i<=n;++i)
    			if(!book[i])
    			{
    				int ta=getf(i);
    				dfs(root[ta],0);
    				ans+=min(dp[ta][0],dp[ta][1]);
    			}
    		printf("%d",ans);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    如何阅读论文(译)
    Linux运维小知识
    认识Linux分区
    如何获取离线安装Chrome扩展程序的包
    Centos 7.4 下初探Zabbix安装
    尝试在Linux上部署Asp.net Core应用程序
    Centos 7.3下图文安装SQL Server
    Asp.net MVC Razor常见问题及解决方法
    轻量级高性能ORM框架:Dapper高级玩法
    Asp.net MVC 如何对所有用户输入的字符串字段做Trim处理
  • 原文地址:https://www.cnblogs.com/Call-me-zhz/p/11321803.html
Copyright © 2020-2023  润新知