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