zoukankan      html  css  js  c++  java
  • Hamiltonian Spanning Tree(DFS+最小生成树)

    题目链接:【codeforces 618D】

    给出一个由n个节点和(n-1)条边组成的生成树,这棵生成树是从包含这n个节点的完全图中出来的,生成树上边的权值是x,在完全图中但是不在生成树上的边的权值是y,求将所有的几点遍历一遍的最短路径

    最短路径中每个点最多连着两条边,分两类讨论:

    1、x<y  ==> 使得最短路径中的边尽可能多的在生成树中

    随便定义一个点作为起点,dfs跑一边,边跑边记录节点v还剩下几条边可以连(就是代码中的len),并用ans来记录生成树上的边的条数

    2、x>=y  ==>  使得最短路径中的边尽可能多的不在生成树中

    当生成树上有节点连的边数是n-1时,必定会有1条边在生成树上,否则就是0条

    参考:codeforces 618D Hamiltonian Spanning Tree(dfs)

    /***********************************************/
    int n,x,y;
    vector<int>G[N];
    int ans=0;
    int dfs(int p,int pr)//p是当前点,pr是上一个点
    {
    	int len=2;
    	for(int i=0;i<G[p].size();i++)
    	{
    		if(G[p][i]==pr) continue;
    		int x=dfs(G[p][i],p);
    		//x表示后一个点是否可以与p点连接(每个点只能连接两条边) 
    		if(len>0 && x==1 ) ans++,len--;
    		
    	}
    	return len>0;//返回值表示此点是否还可以连接 
    }
    
    int main()
    {
    	std::ios::sync_with_stdio(false);
        std::cin.tie(0);
    	cin>>n>>x>>y;
    	for(int i=1;i<n;i++)
    	{
    		int p,q;
    		cin>>p>>q;
    		G[p].push_back(q);
    		G[q].push_back(p);
    	}
    	if(x<y)
    	{
    		dfs(1,-1);
    		ll o=1ll*ans*x+1ll*(n-ans-1)*y;
    		cout<<o<<endl;
    	}
    	else
    	{
    		for(int i=1;i<=n;i++)
    		{
    			if(G[i].size()==n-1)
    			{
    				cout<<1ll*x+1ll*y*(n-2)<<endl;
    				return 0;
    			}
    		}
    		cout<<1ll*y*(n-1)<<endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    区间DP——石子合并
    线性DP-最短编辑距离、编辑距离
    生成树协议
    交换机技术
    以太网原理
    接口知识点
    目前在中国有影响的几种现场总线比较
    委托
    C#有关继承知识点
    C#数组总结
  • 原文地址:https://www.cnblogs.com/liuyongliu/p/10418848.html
Copyright © 2011-2022 走看看