AtCoder AGC038D Unique Path (图论)
生活随笔
收集整理的這篇文章主要介紹了
AtCoder AGC038D Unique Path (图论)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
https://atcoder.jp/contests/agc038/tasks/agc038_d
題解
orz zjr神仙做法
考慮把所有\(C_i=0\)的提示的兩點連邊,那么連完之后的每個連通塊都是一棵樹
那么同一連通塊內就不能出現\(C_i=1\)的提示,然后不同連通塊之間可以任意連邊,但是要滿足兩個連通塊之間只能連一條邊,還要連通
設有\(c\)個連通塊,那么就要在連通塊之間連\(m-(n-c)\)條邊
如果沒有\(C_i=1\)的提示,就只要求\(c-1\le m-(n-c)\le \frac{c(c-1)}{2}\)
如果有,就要求\(\max(3,c)\le m-(n-c)\le \frac{c(c-1)}{2}\)
時間復雜度\(O(n)\)
代碼
#include<cstdio> #include<cstdlib> #include<cassert> #include<iostream> #define llong long long using namespace std;inline int read() {int x=0; bool f=1; char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=0;for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');if(f) return x;return -x; }const int N = 2e5; struct Element {int u,v,typ; } a[N+3]; int uf[N+3]; int n,q,c; llong m;int findfa(int u) {return uf[u]==u?u:uf[u]=findfa(uf[u]);}int main() {scanf("%d%lld%d",&n,&m,&q);for(int i=1; i<=n; i++) uf[i] = i;for(int i=1; i<=q; i++){scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].typ); a[i].u++; a[i].v++;if(a[i].typ==0){int uu = findfa(a[i].u),vv = findfa(a[i].v);if(uu!=vv) {uf[uu] = vv;}}}int cnt1 = 0; c = 0;for(int i=1; i<=n; i++) {if(i==findfa(i)) c++;}for(int i=1; i<=q; i++){if(a[i].typ==1){cnt1++;int uu = findfa(a[i].u),vv = findfa(a[i].v);if(uu==vv) {puts("No"); return 0;}}}llong l = cnt1?max(3ll,(llong)c):c-1ll,r = 1ll*c*(c-1ll)/2ll;if(m-(n-c)>=l && m-(n-c)<=r) {puts("Yes");}else {puts("No");}return 0; }總結
以上是生活随笔為你收集整理的AtCoder AGC038D Unique Path (图论)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AtCoder AGC004E Salv
- 下一篇: AtCoder AGC038F Two