• #环#nssl 1487 图


    题目

    在一个(n)个节点(n)条边的连通图中,
    每条边的权值为两个端点的权值的和。
    已知各边权值,求各点权值
    (保证环的大小一定是奇数)


    分析

    考虑断掉环的某一条边,设根节点的答案为(ax+b,a=1,b=0)
    推出其它点的表示,再根据断掉的边的答案求出(x),代入所有点的权值得出答案


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstdlib> 
    #define rr register
    using namespace std;
    const int N=100011;
    struct node{int y,w,next;}e[N<<1];
    struct rec{int x,y;}dp[N];
    int v[N],as[N],n,k=1,ANS,H;
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f; 
    }
    inline void dfs1(int x,int fa){
    	v[x]=1;
    	for (rr int i=as[x];i;i=e[i].next)
    	if (e[i].y!=fa){
    		if (v[e[i].y]) H=i;
    		    else dfs1(e[i].y,x);
    	}
    }
    inline void dfs2(int x,int fa){
    	for (rr int i=as[x];i;i=e[i].next)
    	if (e[i].y!=fa&&i!=H&&i!=(H^1)){
    		dp[e[i].y]=(rec){-dp[x].x,e[i].w-dp[x].y};
    		dfs2(e[i].y,x);
    	}
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    signed main(){
    	n=iut(),dp[1]=(rec){1,0};
    	for (rr int i=1;i<=n;++i){
    		rr int x=iut(),y=iut(),z=iut();
    		e[++k]=(node){y,z,as[x]},as[x]=k;
    		e[++k]=(node){x,z,as[y]},as[y]=k;
    	}
    	dfs1(1,0),dfs2(1,0); rr int X=e[H].y,Y=e[H^1].y,W=e[H].w;
    	rr rec T=(rec){dp[X].x+dp[Y].x,dp[X].y+dp[Y].y}; ANS=(W-T.y)/T.x;
    	for (rr int i=1;i<=n;++i){
    		rr int ans=ANS*dp[i].x+dp[i].y;
    		if (ans<0) putchar('-'),ans=-ans;
    		print(ans),putchar(10);
    	}
    	return 0;
    }
    
  • 相关阅读:
    audio_policy.conf说明(翻译)
    Qt
    linux C
    Linux C
    Linux C
    Qt
    Qt
    JSON
    JSON
    Qt
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13523051.html
Copyright © 2020-2023  润新知