zoukankan      html  css  js  c++  java
  • 「Luogu P3931」SAC E#1

    原题面

    我环顾四周,发现大佬们的写法都好高端!

    比较差劲的我,只能交上一份DFS的题解

    思路:

    DFS(当然了,其他算法也行)

    要想切断叶子节点根节点的连接

    就是在叶子节点根节点之间砍掉一条边

    这明显就很符合DFS的性质,一条路一直走下去,遇到分枝就分开走

    于是我们DFS每一条路径,然后求答案

    复杂度为O(n)

    但是——还没完!

    我们可以发现DFS有三种情况

    1、该节点为叶子节点,此时只能删去连接它和父节点的边

    2、该节点为枝节点,有父节点和子节点,需要选择性的删除

    3、该节点为根节点,只有子节点,只能删去连接它和子节点的边

    Code:

    #include<bits/stdc++.h>
    #define INF 0x7f7f7f7f
    using namespace std;
    struct node{
    	int to,cost;
    	int nxt;
    	node(int a,int b):to(a),cost(b){	}
    	node(){	}
    }b[200010];
    int n,t,r;
    int head[100010];
    int read()
    {
    	int s=0;
    	char c=getchar();
    	while(!isdigit(c))
    		c=getchar();
    	while(isdigit(c))
    	{
    		s=(s<<1)+(s<<3)+c-'0';
    		c=getchar();
    	}
    	return s;
    }
    void add(int x,int y,int cost)//建边
    {
    	b[++t]=node(y,cost);
    	b[t].nxt=head[x];
    	head[x]=t;
    	b[++t]=node(x,cost);
    	b[t].nxt=head[y];
    	head[y]=t;
    	return;
    }
    int Get(int k,int in)
    {
    	int i;
    	int res=0;
    	for(i=head[k];i;i=b[i].nxt)
    		if(i!=(in^1))//成对变换原理,异或值相同但方向相反的边为一组,避免重复
    			res+=Get(b[i].to,i);
    	if(!b[head[k]].nxt&&k!=r)//确定是叶子节点
    		res=b[in].cost;
    	else
    		res=min(res,b[in].cost);//否则两种方法选其一
    	return res;
    }
    int main()
    {
    	int i;
    	int x,y,cost;
    	n=read();r=read();
    	t=1;//初始赋1,利于成对变换
    	for(i=1;i<n;i++)
    	{
    		x=read();y=read();cost=read();
    		add(x,y,cost);
    	}
    	b[0].cost=INF;//对于根节点的双重保险,防止出什么岔子,比如结果为0
    	printf("%d",Get(r,0));
    	return 0;
    }
    
    
  • 相关阅读:
    如何删除日志?
    sql lock
    生成DAL
    字符串ID替换
    精典SQL:分组合并列值
    SQL Server2005 XML数据类型基础
    Buckup
    SQL试题
    SQL处理表重复记录
    Left Join 中on与where的区别
  • 原文地址:https://www.cnblogs.com/hovny/p/10139338.html
Copyright © 2011-2022 走看看