QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#555182 | #7415. Fast Spanning Tree | yz_ly | WA | 3ms | 20000kb | C++14 | 2.6kb | 2024-09-09 20:25:53 | 2024-09-09 20:25:54 |
Judging History
answer
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int f=1,x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
inline void work(int k){
if(k<0){
putchar('-');
k=-k;
}
if(k>9)
work(k/10);
putchar(k%10+'0');
}
/*
首先x+y>=S,那么有x>=S/2或者y>=S/2
那么对于一个限制,如果现在它不满足,那么满足的时候一定有x'>=x+(S-x-y)/2或者y'>=y+(S-x-y)/2
所以将新的限制加进去
然后每次暴力扫每个连通块,check是否有边满足条件,有就删除这条边,否则加入新的限制
限制用小根堆就行了,合并两个连通块用启发式合并
因为每条边的限制每次一定会/2,所以每条边最多访问logV次,时间复杂度O(nlog^2n+nlogV)
*/
int n,m,boss[300005],siz[300005],vis[300005];
ll w[300005];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q[300005];
set<int> h;
vector<int> ans;
struct q1{
int u,w,v;
}a[300005];
int find(int x){
if(boss[x]!=x)
return boss[x]=find(boss[x]);
return x;
}
bool merge(int x,int y){
int k=find(x),k1=find(y);
if(k==k1)
return false;
if(siz[k]<siz[k1])
swap(k,k1);
boss[k1]=k;
siz[k]+=siz[k1];
w[k]+=w[k1];
while(!q[k1].empty()){
if(!vis[q[k1].top().second])
q[k].emplace(q[k1].top());
q[k1].pop();
}
return true;
}
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++){
w[i]=read();
siz[i]=1;
boss[i]=i;
}
for(int i=1,x,y,z;i<=m;i++){
x=read();
y=read();
z=read();
a[i]=q1{x,y,z};
if(w[x]+w[y]>=z)
h.insert(i);
else{
q[x].emplace(make_pair(w[x]+(z-w[x]-w[y]+1)/2,i));
q[y].emplace(make_pair(w[y]+(z-w[x]-w[y]+1)/2,i));
}
}
while(h.size()){
int id=(*h.begin());
h.erase(h.begin());
vis[id]=1;
if(!merge(a[id].u,a[id].w))
continue;
ans.emplace_back(id);
int rt=find(a[id].u);
while(q[rt].size()&&(vis[q[rt].top().second]||find(a[q[rt].top().second].u)==find(a[q[rt].top().second].w))){
q[rt].pop();
}
while(q[rt].size()&&w[rt]>=q[rt].top().first){
h.insert(q[rt].top().second);
q[rt].pop();
}
if(q[rt].size()){
id=q[rt].top().second;
ll delta=(a[id].v-w[find(a[id].u)]-w[find(a[id].w)]+1)/2;
q[find(a[id].u)].emplace(make_pair(w[find(a[id].u)]+delta,id));
q[find(a[id].w)].emplace(make_pair(w[find(a[id].w)]+delta,id));
}
}
work(ans.size());
putchar('\n');
for(auto i:ans){
work(i);
putchar(' ');
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 17956kb
input:
5 5 1 4 3 4 0 4 5 5 3 1 1 2 5 2 4 3 1 4 1 4
output:
4 2 3 1 4
result:
ok 5 number(s): "4 2 3 1 4"
Test #2:
score: 0
Accepted
time: 0ms
memory: 15968kb
input:
3 5 3 2 2 1 2 6 1 2 6 1 2 3 1 2 6 2 3 6
output:
2 3 5
result:
ok 3 number(s): "2 3 5"
Test #3:
score: 0
Accepted
time: 3ms
memory: 20000kb
input:
10 20 4 6 6 1 7 9 1 8 7 9 5 3 2 1 10 10 5 6 7 9 6 9 3 1 1 6 8 1 5 7 0 9 5 4 10 3 4 8 6 8 3 10 6 5 3 8 3 7 9 1 9 10 10 1 0 5 7 6 6 10 1 6 5 9 5 8 2 9 2 4
output:
8 1 2 3 4 5 6 7 20
result:
ok 9 numbers
Test #4:
score: 0
Accepted
time: 0ms
memory: 15896kb
input:
10 20 0 10 4 6 2 0 2 0 2 8 5 10 8 7 1 6 10 5 0 9 8 0 5 8 4 5 1 8 10 3 6 5 4 3 9 2 6 10 3 6 4 3 1 3 10 3 6 1 3 3 2 5 6 9 2 4 2 5 10 6 5 8 6 3 2 1 0 2 3 6
output:
9 1 4 5 6 2 7 8 9 13
result:
ok 10 numbers
Test #5:
score: -100
Wrong Answer
time: 0ms
memory: 19940kb
input:
100 200 49 21 70 93 66 51 36 59 56 62 10 4 46 73 22 48 89 17 72 60 29 64 19 56 32 54 55 0 77 86 34 35 56 17 55 2 98 80 73 71 64 37 61 22 89 96 99 28 0 35 56 45 74 81 30 3 66 96 28 16 29 43 60 61 60 95 83 5 73 1 28 47 73 44 8 4 91 34 100 23 4 93 44 87 72 5 13 88 100 52 56 61 100 80 14 30 59 97 51 43 ...
output:
96 1 2 4 5 6 7 8 10 11 12 13 14 15 16 17 18 19 9 20 21 22 23 25 26 3 27 28 29 30 31 32 33 35 36 37 38 39 40 41 42 44 45 46 47 48 49 50 51 52 53 34 54 55 56 58 59 60 61 43 62 63 64 66 67 68 69 70 71 72 74 76 78 80 81 82 87 89 91 94 95 96 100 101 24 84 107 109 110 117 119 129 142 144 169 170 195
result:
wrong answer 60th numbers differ - expected: '62', found: '43'