• Rinne Loves Edges


    Rinne Loves Edges

    Problem:

    Rinne 最近了解了如何快速维护可支持插入边删除边的图,并且高效的回答一下奇妙的询问。

    她现在拿到了一个 n 个节点 m 条边的无向连通图,每条边有一个边权 (w_i)

    现在她想玩一个游戏:选取一个 “重要点” S,然后选择性删除一些边,使得原图中所有除 S 之外度为 1 的点都不能到达 S。

    定义删除一条边的代价为这条边的边权,现在 Rinne 想知道完成这个游戏的最小的代价,这样她就能轻松到达 rk1 了!作为回报,她会让你的排名上升一定的数量。

    Input:

    第一行三个整数 N,M,S,意义如「题目描述」所述。

    接下来 M 行,每行三个整数 u,v,w 代表点 u 到点 v 之间有一条长度为 w 的无向边。

    Output:

    一个整数表示答案。

    Example:

    Input

    4 3 1 
    1 2 1 
    1 3 1 
    1 4 1
    

    Output

    3
    

    Note

    需要使得点 2,3,4 不能到达点 1,显然只能删除所有的边,答案为 3

    Input

    4 3 1 
    1 2 3 
    2 3 1 
    3 4 2
    

    Output

    1
    

    Note

    需要使得点 4 不能到达点 1,显然删除边 (2 leftrightarrow 3)是最优的。

    Remark:

    (2 leq S leq N leq 10^5),M=N−1,保证答案在 C++ long long 范围内。

    题解:

    有n个点m调边并且m=n-1可知这个无向连通图是一颗树,因此求解删除一些边使度为1的点无法到达S的问题就转化为了,使叶子节点无法到达S(转化为了以S为根的树)的删除方案,用dfs搜索每次维护删除当前节点和父亲节点之间的边和所有子节点的删除方案的最小值:

    [ans=min(dis[fa][now],sum_{i=1}^{edges}ans_i) ]

    Code:

    /**********************************************************
    * @Author: 			   Kirito
    * @Date:   			   2020-07-28 07:47:01
    * @Last Modified by:   Kirito
    * @Last Modified time: 2020-07-28 08:23:58
    * @Remark: 
    **********************************************************/
    #include <bits/stdc++.h>
    #define lowbit(x) (x&(-x))
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define INF 0x3f3f3f3f
    #define Abs(x) (x>=0?x:(-x))
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll , ll> pll;
    
    const int maxn=111111;
    const ll upround=1e18;
    vector<pll> tree[maxn];
    int n,m,s,book[maxn];
    
    ll dfs(ll fw,ll now)
    {
    	ll ans=0;
    	for(auto &k:tree[now]){
    		if(book[k.first]==0){
    			book[k.first]=1;
    			ans+=dfs(k.second,k.first);
    			book[k.first]=0;
    		}
    	}
    	if(ans==0)
    		return fw;
    	return min(fw,ans);
    }
    
    int main()
    {
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	FAST;
    	cin>>n>>m>>s;
    	for(int i=0;i<m;i++){
    		int x,y,w;
    		cin>>x>>y>>w;
    		tree[x].push_back(make_pair(y,w));
    		tree[y].push_back(make_pair(x,w));
    	}
    	book[s]=1;
    	cout<<dfs(upround,s);
    	return 0;
    }
    
  • 相关阅读:
    js获取url传递参数
    C#:String.Format数字格式化输出
    mathjs,math.js解决js运算精度问题
    js获取文件后缀
    vue生成二维码插件qrcodejs2
    多行文本超出后隐藏,超出3行隐藏
    vue点击按钮给商品按照价格进行倒叙
    vue关闭代码检查eslint
    vue + elementUi + upLoadIamge组件 上传文件到阿里云oss
    nodejs+expressjs+ws实现了websocket即时通讯,服务器和客户端互相通信
  • 原文地址:https://www.cnblogs.com/LeafLove/p/13389019.html
Copyright © 2020-2023  润新知