Solution

由题意可知给定的图是一棵树。树上的最优化问题可以想到树形

按照常用的状态设计方式,可以设 为根节点为 的最少代价。使以 为根的子树的叶子节点无法到达 的方式有两种:

  • 割断与 直接相连的边
  • 割断与 的子节点直接相连的边

两种方式取最小值即可。故状态转移方程为

其中 为与 直接相连的子节点。

因此可以以 节点为根,进行 ,目标状态为

时间复杂度:

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const ll maxn=2e5+10;
ll n,m,s,cnt,d[maxn],hd[maxn],f[maxn];
struct edge{
    ll t,v,w;
}e[maxn<<1];
void add(ll x,ll y,ll z){
    cnt++;
    e[cnt].t=hd[x];
    e[cnt].v=y;
    e[cnt].w=z;
    hd[x]=cnt;
}
void Dfs(ll u,ll fa){
    if(d[u]==1&&u!=s)
        return;
    f[u]=0;
    for(int i=hd[u];i!=0;i=e[i].t)
        if(e[i].v!=fa){
            Dfs(e[i].v,u);
            f[u]+=min(f[e[i].v],e[i].w);
        }
    return;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m>>s;
    ll x,y,z;
    for(int i=1;i<=m;i++){
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
        d[x]++,d[y]++;
    }
    memset(f,0x7f,sizeof(f));
    Dfs(s,0);
    cout<<f[s];
    return 0;
}