HDU - 1824 Let's go home
Let’s go home
Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2756 Accepted Submission(s): 1192
Problem Description
小時候,鄉(xiāng)愁是一枚小小的郵票,我在這頭,母親在那頭。
—— 余光中
集訓(xùn)是辛苦的,道路是坎坷的,休息還是必須的。經(jīng)過一段時間的訓(xùn)練,lcy決定讓大家回家放松一下,但是訓(xùn)練還是得照常進行,lcy想出了如下回家規(guī)定,每一個隊(三人一隊)或者隊長留下或者其余兩名隊員同時留下;每一對隊員,如果隊員A留下,則隊員B必須回家休息下,或者B留下,A回家。由于今年集訓(xùn)隊人數(shù)突破往年同期最高記錄,管理難度相當大,lcy也不知道自己的決定是否可行,所以這個難題就交給你了,呵呵,好處嘛~,免費**漂流一日。
Input
第一行有兩個整數(shù),T和M,1<=T<=1000表示隊伍數(shù),1<=M<=5000表示對數(shù)。
接下來有T行,每行三個整數(shù),表示一個隊的隊員編號,第一個隊員就是該隊隊長。
然后有M行,每行兩個整數(shù),表示一對隊員的編號。
每個隊員只屬于一個隊。隊員編號從0開始。
Output
可行輸出yes,否則輸出no,以EOF為結(jié)束。
Sample Input
1 2
0 1 2
0 1
1 2
2 4
0 1 2
3 4 5
0 3
0 4
1 3
1 4
Sample Output
yes
no
一道比較明顯的2-SAT,現(xiàn)在我們主要考慮如何建圖。
考慮建圖:
對于第一種隊伍關(guān)系:
對于第二種關(guān)系:
然后對于每個隊員跑一次tarjan即可,但是這道題并沒有說隊員是連續(xù)的,而是說每個隊員有編號,所以我們要用map來離散化每個隊員的編號。但是好像這道題數(shù)據(jù)比較水,不離散化,當成編號連續(xù)也能AC
然后檢查每個隊員,如果這個隊員走和這個隊員留在同一個強連通分量當中,就輸出no,不然輸出yes
AC代碼:
#pragma GCC optimize(2) #include<bits/stdc++.h> //#define int long long using namespace std; const int N=10010,M=100010; int n,m,dfn[N],col[N],low[N],vis[N],cnt,co,base,flag,idx; int head[N],nex[M],to[M],tot; stack<int> st; unordered_map<int,int> mp; inline void add(int a,int b){to[++tot]=b; nex[tot]=head[a]; head[a]=tot; } inline void init(){memset(head,0,sizeof head); memset(dfn,0,sizeof dfn);memset(low,0,sizeof low); memset(col,0,sizeof col);cnt=co=tot=flag=idx=0; mp.clear(); } void tarjan(int x){dfn[x]=low[x]=++cnt; st.push(x); vis[x]=1;for(int i=head[x];i;i=nex[i]){if(!dfn[to[i]]){tarjan(to[i]); low[x]=min(low[x],low[to[i]]);}else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);}if(dfn[x]==low[x]){co++;while(1){int u=st.top(); st.pop(); vis[u]=0;col[u]=co; if(u==x) return ;}} } signed main(){while(~scanf("%d %d",&n,&m)){init(); base=3*n;for(int i=1;i<=n;i++){int a,b,c; scanf("%d %d %d",&a,&b,&c);mp[a]=++idx; mp[b]=++idx; mp[c]=++idx;add(mp[a]+base,mp[b]); add(mp[a]+base,mp[c]);add(mp[b]+base,mp[a]); add(mp[b]+base,mp[c]+base);add(mp[c]+base,mp[a]); add(mp[c]+base,mp[b]+base);add(mp[a],mp[b]+base); add(mp[a],mp[c]+base);add(mp[b],mp[a]+base); add(mp[b],mp[c]);add(mp[c],mp[a]+base); add(mp[c],mp[b]);}while(m--){int a,b; scanf("%d %d",&a,&b);add(mp[a],mp[b]+base); add(mp[b],mp[a]+base); }for(int i=1;i<=6*n;i++) if(!dfn[i]) tarjan(i);for(int i=1;i<=base&&!flag;i++) if(col[i]==col[i+base]) flag++;puts(flag?"no":"yes");}return 0; }總結(jié)
以上是生活随笔為你收集整理的HDU - 1824 Let's go home的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cannot access ‘route
- 下一篇: 广州电信最新DNS更新