2109D Div. 2 Round 1025
题意
给定若干个元素 , 判断跨过其中若干元素的和数量条边是否可以从一个图的源点到达其他点
思路
和某个洛谷的题很像 , 首先单源最短路 , 且无边权 , 所以用bfs , 然后考虑更新到每个点的奇数路径长度和偶数路径长度即可
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long int
inline int read() {
int ans = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans * f;
}
const int N = 2e5+10;
int b[N];
vector<int> ed[N];
int idx;
int odd[N],even[N];
int n,m,l;
typedef pair<int,int> PII;
void bfs() {
for (int i =1; i<= n;i++) {
odd[i] =2e9+10;
even[i] =2e9+10;
}
queue<PII> q;
q.push({1,0});
even[1] = 0;
while (q.size()) {
auto [u,p] = q.front();q.pop();
for (auto e : ed[u]) {
if (p&1) {
//even
if (even[e] > p + 1) {
even[e] = p+1;
q.push({e,p+1});
}
}
else {
if (!(p&1)) {
//odd
if (odd[e] > p+1) {
odd[e] = p+1;
q.push({e,p+1});
}
}
}
}
}
}
void solve() {
int sum=0,oddsum=0,evensum =0;
idx=0;
n=read(),m=read(),l=read();
for (int i = 1; i<= l; i++) {
int tmp=read();
if (!(tmp&1))
sum+=tmp;
else
b[++idx] = tmp;
}
for (int i = 1; i<=m;i++) {
int u=read(),v=read();
ed[u].push_back(v);
ed[v].push_back(u);
}
sort(b+1,b+1+idx);
reverse(b+1,b+1+idx);
for (int i =1; i<= idx; i++) {
if (i!= idx) {
oddsum += b[i];
evensum += b[i];
}
else {
oddsum += idx&1?b[idx]:0;
evensum += idx&1?0:b[idx];
}
}
if (idx)
oddsum += sum;
evensum += sum;
bfs();
for (int i =1;i<=n;i++) {
if (even[i] <= evensum || odd[i] <= oddsum) {
cout<<1;
}
else {
cout<<0;
}
}
cout<<"\n";
for (int i = 1; i<= n;i++) {
ed[i].clear();
}
}
signed main() {
int t;
cin>>t;
while (t--) solve();
return 0;
}

浙公网安备 33010602011771号