#include <bits/stdc++.h>
using namespace std;
#define int long long
struct grup
{
vector<int>noduri_alive;
int nr_oameni;
multiset<pair<int,int>> edges;
};
int n,m,s[200005];
vector<pair<int,int>>G[200005];
int t[200005],sz[200005];
grup g[200005];
bool sol_finala[200005];
bool cmp(int x,int y)
{
if (g[x].nr_oameni != g[y].nr_oameni)
return g[x].nr_oameni < g[y].nr_oameni;
return x < y;
}
multiset<int,decltype(cmp)*>st(cmp);
int ancestor(int nod)
{
while (nod != t[nod])
nod = t[nod];
return nod;
}
void join(int x,int y)
{
if (sz[x] < sz[y])
swap(x,y);
sz[x] += sz[y];
t[y] = x;
g[x].nr_oameni += g[y].nr_oameni;
for (auto it : g[y].noduri_alive)
g[x].noduri_alive.push_back(it);
for (auto it : g[y].edges)
g[x].edges.insert(it);
g[y].nr_oameni = 0;
g[y].noduri_alive.clear();
g[y].edges.clear();
st.insert(x);
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> s[i];
for (int i = 1; i <= m; i++)
{
int x,y;
cin >> x >> y;
G[x].push_back({s[y],y});
G[y].push_back({s[x],x});
}
for (int i = 1; i <= n; i++)
{
t[i] = i;
sz[i] = 1;
g[i].noduri_alive = {i};
g[i].nr_oameni = s[i];
for (auto it : G[i])
g[i].edges.insert(it);
st.insert(i);
}
while (st.size() >= 2)
{
/*for (auto it : st)
{
cout << it << ' ' << g[it].nr_oameni << endl;
for (auto itt : g[it].noduri_alive)
cout << itt << ' ';
cout << endl;
for (auto itt : g[it].edges)
cout << itt.first << ' ' << itt.second << endl;
cout << endl;
}
cout << endl;*/
int nod = *st.begin();
//cout << nod << endl;
while (true)
{
pair<int,int>aux = *(g[nod].edges.begin());
if (ancestor(aux.second) == nod)
g[nod].edges.erase(g[nod].edges.begin());
else
break;
}
pair<int,int>aux = *(g[nod].edges.begin());
//cout << aux.first << ' ' << aux.second << endl;
g[nod].edges.erase(g[nod].edges.begin());
if (aux.first > g[nod].nr_oameni)
{
//cout << "caz1 " << nod << endl;
st.erase(st.find(nod));
g[nod].noduri_alive.clear();
}
else
{
//cout << "caz2 " << nod << ' ';
int x = aux.second;
x = ancestor(x);
//cout << x << endl;
st.erase(st.find(nod));
//cout << st.size() << endl;
if (st.find(x) != st.end())
st.erase(st.find(x));
join(nod,x);
}
}
for (auto it : st)
{
for (auto x : g[it].noduri_alive)
sol_finala[x] = true;
}
for (int i = 1; i <= n; i++)
{
if (sol_finala[i] == false)
cout << 0;
else
cout << 1;
}
return 0;
}
/**
fiecare muchie devine defapt doua muchii, una x -> y cu cost s[y] si una y -> x cu cost s[x]
iau grupul cu macar un nod alive cu cei mai putini oameni si muchia lui spre un nod cu s cat mai mic
daca nu le pot conecta, marchez ca not alive toate nodurile alive din grup
daca le pot conecta, fac un small to large pe noduri (nu conteaza daca alive sau nu) pentru a le uni
ok, idee penala, acum ramane cum implementez
tin un dsu pentru grupuri, iar in tatal grupului tin:
-nodurile alive din grup
-cate alive am
-cati oameni am
-muchiile, sortate dupa cost
imi pot tine un set cu tatii grupurilor cu macar un nod alive, pentru fiecare retinand:
-ofc nodul tata
-numarul de oameni
o sa am ceva gen:
while (setul mai are >= 2 grupuri alive)
{
iau si eu grupul din set cu numar minim de oameni
lui ii iau muchia minima pentru care nu sunt ambele noduri conectate de muchie in grupul lui nod
daca pe muchia asta nu pot conecta, atunci scot din set nodul nod (si atat)
daca pe muchia asta pot conecta, am doua cazuri:
1. nodul de care conectez nu e alive -> il scot pe asta din set, le dau join si bag combinata lor in set
2. nodul de care conectez e alive -> ii scot pe ambii din set, le dau join si bag combinata lor in set
}
apoi, din grupul care mi-a mai ramas singur in set, afisez alea alive
**/
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
24920 KB |
Output is correct |
2 |
Correct |
4 ms |
24924 KB |
Output is correct |
3 |
Correct |
5 ms |
25080 KB |
Output is correct |
4 |
Runtime error |
24 ms |
51476 KB |
Execution killed with signal 11 |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
24920 KB |
Output is correct |
2 |
Correct |
5 ms |
24924 KB |
Output is correct |
3 |
Correct |
655 ms |
85496 KB |
Output is correct |
4 |
Correct |
403 ms |
78380 KB |
Output is correct |
5 |
Correct |
656 ms |
81132 KB |
Output is correct |
6 |
Correct |
662 ms |
82884 KB |
Output is correct |
7 |
Correct |
691 ms |
83032 KB |
Output is correct |
8 |
Correct |
423 ms |
78372 KB |
Output is correct |
9 |
Correct |
442 ms |
82648 KB |
Output is correct |
10 |
Correct |
288 ms |
75704 KB |
Output is correct |
11 |
Correct |
379 ms |
79604 KB |
Output is correct |
12 |
Correct |
577 ms |
78796 KB |
Output is correct |
13 |
Correct |
390 ms |
78124 KB |
Output is correct |
14 |
Correct |
397 ms |
78280 KB |
Output is correct |
15 |
Correct |
383 ms |
80248 KB |
Output is correct |
16 |
Correct |
275 ms |
77252 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
24924 KB |
Output is correct |
2 |
Runtime error |
753 ms |
153344 KB |
Execution killed with signal 11 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
24924 KB |
Output is correct |
2 |
Runtime error |
266 ms |
154244 KB |
Execution killed with signal 11 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
24920 KB |
Output is correct |
2 |
Correct |
4 ms |
24924 KB |
Output is correct |
3 |
Correct |
5 ms |
25080 KB |
Output is correct |
4 |
Runtime error |
24 ms |
51476 KB |
Execution killed with signal 11 |
5 |
Halted |
0 ms |
0 KB |
- |