At373 D - Hidden Weights

D.Avoid K Palindrome

原题链接

Problem Statement

You are given a directed graph with \(N\) vertices and \(M\) edges. The \(j\)-th directed edge goes from vertex \(u_j\) to vertex \(v_j\) and has a weight of \(w_j\).

Find one way to write an integer between \(-10^{18}\) and \(10^{18}\), inclusive, to each vertex such that the following condition is satisfied.

  • Let \(x_i\) be the value written on vertex \(i\). For all edges \(j=1,2,\dots,M\), it holds that \(x_{v_j} - x_{u_j} = w_j\).

It is guaranteed that at least one such assignment exists for the given input.

Constraints:

  • \(2 \leq N \leq 2 \times 10^5\)
  • \(1 \leq M \leq \min\{2 \times 10^5,N(N-1)/2\}\)
  • \(1 \leq u_j, v_j \leq N\)
  • \(u_j \neq v_j\)
  • If \(i \neq j\), then \((u_i, v_i) \neq (u_j, v_j)\) and \((u_i, v_i) \neq >(v_j, u_j)\)
  • \(|w_j| \leq 10^9\)
  • All input values are integers.
  • There exists at least one assignment satisfying the conditions.

Sample Input:

3 3
1 2 2
3 2 3
1 3 -1

Sample Output:

3 5 2

By setting \(x = (3, 5, 2)\), we have \(x_2 - x_1 = w_1 = 2\), \(x_2 - x_3 = w_2 = 3\), \(x_3 - x_1 = w_3 = -1\), satisfying the conditions.

For example, \(x = (-1, 1, -2)\) is also a valid answer.

解题思路:

首先能想到的dfs跑一遍有向图,从起点开始给每个点赋值,但是这样肯定会有一些点遍历不到,因为有向图仅满足单向可抵达,这时候要遍历整个图就比较麻烦了。这时考虑反向建图,赋值一个反的边权,这样就从有向图的遍历转化成了无向图。

AC code:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const ll inf=1e18;
const int N=2e5+10;
struct node{
    int u;ll w;
};
vector<node>G[N];
ll res[N];
bool vis[N];
void add(int x,int y,ll w){
    G[x].push_back({y,w});
    G[y].push_back({x,-w});
}
void dfs(const int &u,const int &f){
    for(auto &[v,w]:G[u]){
        if(v==f||vis[v]) continue;
        vis[v]=1;
        res[v]=res[u]+w;
        dfs(v,u);
    }
}
int main(){
    cin.tie(0)->ios::sync_with_stdio(false);
    int n,m;cin>>n>>m;
    for(int i=1,x,y;i<=m;i++){
        ll w;
        cin>>x>>y>>w;
        add(x,y,w);
    }
    for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,0);
    for(int i=1;i<=n;i++) cout<<res[i]<<" \n"[i==n];
    return 0;
}
posted @ 2025-04-21 15:54  usedchang  阅读(27)  评论(0)    收藏  举报