zoukankan      html  css  js  c++  java
  • 题解 UVA10859 【Placing Lampposts】

    交了N次,重构一次代码终于过了.....

    题意:一片森林,1.输出占领所有边需要的最小的路灯个数 2.输出两端点均被占领的边的条数 3.只有一端被占领的边的条数

    还是比较简单的

    开始的时候思路不够清晰,写的时候很多东西都没注意到

    导致一直WA,重构的时候好多了,一遍过

    开两个DP数组,一个存路灯个数,一个存两端都被占领的边的个数
    感觉更好理解一些

    以下是代码

    #include<cstdio>
    #include<cstring>
    #define N 100005
    
    int n,m,cnt,T,ans1,ans2,a,b;
    int head[N],vis[N];
    int dp[N][2],f[N][2];
    
    struct node{
    	int v,nex;
    }e[N];
    
    void dfs(int u,int fa){
    	dp[u][1]=1;
    	vis[u]=1;
    	for(int i=head[u];i;i=e[i].nex){
    		int v=e[i].v;
    		if(vis[v]) continue;
    		dfs(v,u);
    		dp[u][0]+=dp[v][1];
    		f[u][0]+=f[v][1];
    		if(dp[v][1]<dp[v][0]){
    			dp[u][1]+=dp[v][1];
    			f[u][1]+=f[v][1]+1;
    		}
    		else if(dp[v][1]>dp[v][0]){
    			dp[u][1]+=dp[v][0];
    			f[u][1]+=f[v][0];
    		}
    		else{					//这里进行一步特判,满足第二个条件
    			dp[u][1]+=dp[v][0];
    			if(f[v][1]+1>f[v][0]){
    				f[u][1]+=f[v][1]+1;
    			}
    			else{
    				f[u][1]+=f[v][0];
    			}
    		}
    	}
    }
    
    void add(int u,int v){
    	cnt++;
    	e[cnt].v=v;
    	e[cnt].nex=head[u];
    	head[u]=cnt;
    }
    
    void init(){
    	cnt=ans1=ans2=0;
    	memset(head,0,sizeof head);
    	memset(vis,0,sizeof vis);
    	memset(dp,0,sizeof dp);
    	memset(f,0,sizeof f);
    }
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		init();
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=m;i++){
    			scanf("%d%d",&a,&b);
    			a++,b++;
    			add(a,b);add(b,a);
    		}
    		for(int i=1;i<=n;i++){
    			if(!vis[i]){		//可能是森林,注意!!
    				dfs(i,0);
    				if(dp[i][0]>dp[i][1]){
    					ans1+=dp[i][1];
    					ans2+=f[i][1];
    				}
    				else if(dp[i][0]<dp[i][1]){
    					ans1+=dp[i][0];
    					ans2+=f[i][0];
    				}
    				else{			//同上
    					ans1+=dp[i][0];
    					if(f[i][1]>f[i][0]){
    						ans2+=f[i][1];
    					}
    					else{
    						ans2+=f[i][0];
    					}
    				}
    			}
    		}
    		printf("%d %d %d
    ",ans1,ans2,m-ans2);
    	}
    	return 0;
    }
    
  • 相关阅读:
    eclipse下mysql编程
    mysql简单操作一
    Mysql ubuntu下的安装卸载
    c++ 上机实验题
    Android BottomSheet:以选取图片为例(2)
    Android BottomSheet:便捷易用的底部滑出面板(1)
    如何绘制caffe网络训练曲线
    10+资深软件架构师谈计算机专业——填高考志愿必读
    添物不花钱学计算机及编程(预备篇)
    Android StatusBarUtil:设置Android系统下方虚拟键键盘透明度
  • 原文地址:https://www.cnblogs.com/Makerz/p/9308730.html
Copyright © 2011-2022 走看看