C++——NOIP類比題——猴子__C++

來源:互聯網
上載者:User
猴子
題目描述

有 N 只猴子,第一隻尾巴掛在樹上,剩下的 N-1 只,要麼被其他的猴子抓住,要麼抓住了其他的猴子,要麼兩者均有。當然一隻猴子最多抓兩隻另外的猴子,只有兩隻手嘛。現在給出這N只猴子抓與被抓的資訊。

在某個時刻某隻猴子 A 會放掉它左手或右手的猴子 B ,會出現以下三種情況:
1.B 起初並沒有抓住 A,則 B 會掉下;
2.B 起初也抓住了 A,但在 A 放手的同時 B 並沒有放手,則 B 不會掉下;
3.B 起初也抓住了 A,在 A 放手的同時 B 也放手了,則 B 會掉下。

如果 B 掉下,就會同時導致相關猴子也落到地上。求每隻猴子的落地的時間。 輸入格式

第一行兩個數 N、M,表示有 N 只猴子,並且總時間為 M-1 。

接下來 N 行,按編號從 1..N 描述了每隻猴子的資訊,每行兩個整數,第 i 行的兩個數分別表示第 i 只猴子的左手和右手抓的猴子的編號,如果是 -1 ,表示該猴子那隻手沒抓其他的猴子。再接下來 M 行,按時間順序(0~M-1)給出了一些猴子放手的資訊,第 1+N+i 行表示第 i-1 時刻某隻猴子的放手資訊,資訊以兩個數給出,前者表示放手的猴子的編號,後者表示其放的是哪只手,1 左 2 右。 輸出格式

共輸出 N 行,第 i 行表示第 i 只猴子掉落的時刻,若第 i 只猴子到 M-1 時刻以後還沒掉落,就輸出 -1 。 範例資料 1

輸入

3 2 
-1 3 
3 -1 
1 2 
1 2 
3 1

輸出 -1 

1 備忘

【資料範圍】
30% 的資料,N≤1000;M≤1000;
100% 的資料,1≤N≤200000;1≤M≤400000。

解題報告:

可以把每個猴子看成圖中的一個點,猴子之間的關係用無向邊來表示,判斷一隻猴子是否掉落就看其與 1 是否在同一個連通分量中。順著思考問題可能有點困難,可以反過來思考,首先可以求出第 M-1 時刻之後猴子們的情況,然後倒著來,將猴子一隻只“接”上去,這樣問題就變成一隻猴子最早在什麼時候和 1 所處的連通塊並在了一起。對於連通性的維護可以用並查集來實現。

時間效率:
我們用並查集來實現連通性的維護,總的時間效率為O(n*α),其中α為不超過5的數,可以視為常數。

空間效率: 0(N+M)。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>int n,m,cnt,hand[200001][2],ret[400001],t[400001][2],graph[400001],time[400001][2];bool sign[400001];struct node{int tvtx,last;}arc[2000001];inline int readint(){    int i=0,f=1;    char ch;    for(ch=getchar();(ch<'0'||ch>'9') && ch!='-';ch=getchar());    if(ch=='-')    {        f=-1;         ch=getchar();    }    for(;ch>='0' && ch<='9';ch=getchar())        i=(i<<3)+(i<<1)+ch-'0';    return i*f;}inline void add(int a,int b){arc[++cnt].tvtx=b;arc[cnt].last=graph[a];graph[a]=cnt;}inline void dfs(int x,int t){sign[x]=1;ret[x]=t;for(int i=graph[x];i;i=arc[i].last){int v=arc[i].tvtx;if(!sign[v]) dfs(v,t);}}int main(){register int i,j,a,b;n=readint();m=readint();for(i=1;i<=n;++i) hand[i][0]=readint(),hand[i][1]=readint();memset(time,-1,sizeof(time));for(i=1;i<=n;++i) ret[i]=-2;for(i=0;i<m;++i){t[i][0]=readint();t[i][1]=readint();time[t[i][0]][t[i][1]-1]=i;t[i][1]=hand[t[i][0]][t[i][1]-1];}for(i=1;i<=n;++i)for(j=0;j<=1;++j)if(hand[i][j]!=-1&&time[i][j]==-1){add(i,hand[i][j]);add(hand[i][j],i);}dfs(1,-1);for(i=m-1;i>=0;--i){a=t[i][0];b=t[i][1];add(a,b);add(b,a);if(sign[a]&&!sign[b]) dfs(b,i);if(sign[b]&&!sign[a]) dfs(a,i);}for(i=1;i<=n;++i) printf("%d\n",ret[i]);}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.