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 ; }