[蓝桥杯 2022 省 A] 推导部分和——图论建模
Circle_Table · · 题解
这边是题目传送门喵~
欢迎来博客园阅读~
题意简述
给定一个序列以及这个序列几个部分的数字之和,求询问的部分数字之和。
当无法确定时报告无解。
思路
看了题之后感觉不是可以直接上手的那种。想到了将部分和用前缀和的形式转化:设
也就是说,题目给出的
对于每一次询问
我么发现,如果
每一个联通块都有一个
于是对每一个联通块 bfs 就把这个题做完了。
代码
#include <bits/stdc++.h>
#define loop(i,a,b) for(int i=(a);i<=(int)(b);i++)
using namespace std;
typedef long long ll;
const int N=1e5+5;
const ll inf=1e18;
int n,m,q,fa[N];
int find(int x){
if(x==fa[x])return x;
return fa[x]=find(fa[x]);
}
void connect(int u,int v){
int fu=find(u),fv=find(v);
fa[fu]=fv;
return;
}
struct side{
int to;
ll w;
};
vector<side>g[N];
ll sum[N];
bool vis[N];
void bfs(int st){
queue<int>q;
q.push(st);
while(!q.empty()){
int u=q.front();
q.pop();
for(auto s:g[u]){
int v=s.to;
connect(u,v);
sum[v]=sum[u]+s.w;
if(!vis[v])q.push(v),vis[v]=1;
}
}
return;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m>>q;
int l,r;
ll S;
loop(i,1,m){
cin>>l>>r>>S;
g[l-1].push_back({r,S});
g[r].push_back({l-1,-S});
}
loop(i,0,n)fa[i]=i;
loop(i,0,n)if(fa[i]==i)bfs(i);
while(q--){
cin>>l>>r;
if(find(l-1)==find(r))cout<<sum[r]-sum[l-1]<<'\n';
else cout<<"UNKNOWN\n";
}
return 0;
}
完结撒花花~