环求解点值

https://ac.nowcoder.com/acm/contest/3782/A

题意:在一个n个点(编号为1-n),n条边的环中,每条边的长度等于它所连接的两个端点上的数字的和。

现已知将全图连通的n条边的长度,求各点上的数字。

解法:第一次跑环将x1求解出,第二次跑环将各点值求解。

#include <bits/stdc++.h>
#define ME(x , y) memset(x , y , sizeof(x))
#define SC scanf
#define rep(i ,j , n) for(int i = j ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int head[100009] , tol;
int temp , val[100009] , vis[100009];
struct node{
    int to , next , w;
}g[200009];

void add(int u , int v , int w){
    g[++tol].to = v ;
    g[tol].next = head[u];
    g[tol].w = w ;
    head[u] = tol;
}

void dfs1(int u , int pre , int dis){
    if(vis[u]) return;
    vis[u] = 1 ;
    for(int i = head[u] ; i ; i = g[i].next){
        int v = g[i].to;
        if(v == pre) continue;
        if(dis % 2 == 0) temp += g[i].w;
        else temp -= g[i].w;
        dfs1(v , u , dis+1);
        if(u == 1) break;
    }
}

void dfs2(int u , int pre){
    if(vis[u])return;
    vis[u] = 1;
    for(int i = head[u] ; i ; i = g[i].next){
        int v = g[i].to;
        if(v == pre) continue;
        val[v] = g[i].w - val[u];
        dfs2(v , u);
    }
}

int main()
{
    int n ; cin >> n;
    rep(i , 0 , n){
        int u , v , w ;
        scanf("%d%d%d" , &u , &v , &w);
        add(u , v , w);
        add(v , u , w);
    }
    dfs1(1 , -1 , 0);
    val[1] = temp/2;
    memset(vis, 0 , sizeof(vis));
    dfs2(1 , -1);
    for(int i = 1 ; i <= n ; i++){
        cout << val[i]<< endl;
    }
    return 0 ;
}

 三维数组存链式前向星

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ME(x , y) memset(x , y , sizeof(x))
#define SC(n) scanf("%d" , &n)
#define SC scanf
#define rep(i , j , n) for(int i = j ; i < n ; i++)
#define red(i , n , j) for(int i = n-1 ; i >= j ; i--)
#define INF  0x3f3f3f3f
#define mod 998244353
#define PI acos(-1)
#define gcd __gcd
using namespace std;
typedef long long ll ;
ll lcm(ll a, ll b){return a/gcd(a,b)*b;}
ll ksm(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a;a*=a,b>>=1;}return ans;}
const int maxn = 110;
int a[200009][3] , tol , head[100009];
int vis[100009] , bgn , top , val[100009] , s[100009];
void add(int u , int v , int w){
    a[++tol][1] = v;
    a[tol][2] = w ;
    a[tol][0] = head[u];
    head[u] = tol;
}
 
void dfs1(int u , int pre){
    if(vis[u])
    {
        int temp = 0;
        for(int i = vis[u] ; i <= top ; i++)
            temp = s[i] - temp;
        bgn = u ;
        val[bgn] = temp/2;
        return;
    }
    vis[u] = ++top;
    for(int i = head[u] ; i ; i = a[i][0]){
        int v = a[i][1];
        if(v == pre) continue;
        s[top] = a[i][2];
        dfs1(v , u);
        if(bgn) break ;
    }
    top--;
    vis[u] = 0;
}
 
void dfs2(int x)
{
    vis[x] = 1 ;
    for(int i = head[x] ; i ; i = a[i][0]){
        int v = a[i][1];
        if(vis[v]) continue;
        val[v] = a[i][2] - val[x];
        dfs2(v);
    }
}
 
int main()
{
    int n ;
    scanf("%d" , &n);
    rep(i , 0 , n){
        int u , v , w ;
        scanf("%d%d%d" , &u , &v , &w);
        add(u , v , w);
        add(v , u , w);
    }
    dfs1(1 , -1);
    dfs2(bgn);
    for(int i = 1 ; i <= n ; i++){
        cout << val[i] << endl;
    }
    return 0 ;
}

 

posted @ 2020-02-11 19:33  无名菜鸟1  阅读(183)  评论(0编辑  收藏  举报