日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2262: master(vector + dfs)

發(fā)布時(shí)間:2024/4/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2262: master(vector + dfs) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這就是!!!

題目描述

有N個(gè)人,編號(hào)為1至N,他們相互之間拜師學(xué)藝。

某個(gè)時(shí)刻,如果甲向乙拜師,一般情況下乙就將甲收為徒弟。這時(shí)乙會(huì)將甲視為大徒弟,而所有甲的徒弟(如果有的話)便成為乙的小徒弟。

但是,每個(gè)人都不想收太多的大徒弟。如果乙當(dāng)前大徒弟數(shù)量超過他的期望值,他便會(huì)拒絕甲,而讓甲拜自己的某一位大徒弟為師。甲總是想選好的師傅,而如果一個(gè)人的所有徒弟數(shù)量很多,往往說明他水平比較高,所以甲會(huì)選乙的徒弟中,擁有最多徒弟的人。如果有不止一個(gè)人徒弟最多,甲會(huì)選擇最早向乙拜師的那位。于是接下來,就是新的一次拜師過程,甲向乙的某位徒弟拜師。甲直到拜師成功才會(huì)停止。

每個(gè)人每一時(shí)刻最多只會(huì)有一個(gè)師傅。有師傅的人若再向其他人拜師,就會(huì)先斷絕與當(dāng)前師傅的師徒關(guān)系。若甲不認(rèn)乙為師,乙也就不認(rèn)甲為大徒弟,同時(shí)甲和他的徒弟們也因此與甲的師傅脫離關(guān)系(當(dāng)然包括師傅的師傅,師傅的師傅的師傅……)。

兩個(gè)人之間的師徒關(guān)系可能是變化的。所以若甲向乙多次拜師,則甲向乙拜師的時(shí)間將以最后一次拜師的時(shí)間算。

一開始,每個(gè)人都沒有師傅,也沒有徒弟。我們事先告訴你每個(gè)人愿意收的最多大徒弟數(shù)量,達(dá)到了這個(gè)數(shù)量,他就不再收大徒弟,除非又有某個(gè)大徒弟與他斷絕了關(guān)系。接下來每一時(shí)刻,就有人相互拜師,而所有拜師都會(huì)按照上面的規(guī)則進(jìn)行。此外,一個(gè)人也不會(huì)向自己當(dāng)前的任何一位徒弟拜師。
請(qǐng)你統(tǒng)計(jì),所有拜師過程結(jié)束后,每個(gè)人有多少大徒弟,小徒弟。

輸入

第一行給出兩個(gè)整數(shù)N和M(5<=N<=10000,0<=M<=10000),其中N表示總?cè)藬?shù),M表示有多少組拜師的人。

第二行,包含N個(gè)正整數(shù),依次表示每個(gè)人愿意收的最多大徒弟的數(shù)量。

接下來M行,每行兩個(gè)整數(shù)A和B,按時(shí)間順序依次表示一對(duì)拜師的人。總是A向B拜師。

輸出

輸出包括N行,每行有兩個(gè)整數(shù),之間用一個(gè)空格隔開。第i行的兩個(gè)數(shù)分別表示,在所有拜師結(jié)束后,編號(hào)為i的人擁有的大徒弟數(shù)量和小徒弟數(shù)量。

樣例輸入

6 7
2 2 2 2 2 2
2 1
3 1
4 1
5 1
6 1
6 3
3 2

樣例輸出

1 4
2 2
1 0
1 1
0 0
0 0

思路

仔細(xì)讀題實(shí)現(xiàn)不難就是麻煩。
拜師的時(shí)候分兩種情況:

  • 第一次拜師
  • 師傅的徒弟人數(shù)沒有滿直接加入。
  • 師傅的徒弟人數(shù)已滿,遞歸找到人數(shù)最多的徒弟(找人數(shù)最多的徒弟的徒弟…)直到找到徒弟的徒弟還沒有滿就加入
    • 第 2~N 次拜師
  • 把原來的師徒關(guān)系解散,(自己的徒弟不用管)
  • 重復(fù)第一次拜師的過程
  • 主要用到vector 哪里不會(huì)點(diǎn)哪里~

    AC代碼

    #include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<stack> #include<vector> #define N 10004 using namespace std; vector<int>ve[N]; int d[N], tea[N]; int num, flag; int dfs(int x) { //找X的所有徒弟,記得使用前 NUM初始化為零 int t = ve[x].size();if(t) {num += t;}else {return 0;}for(int i = 0; i < t; i++) {dfs(ve[x][i]);}return num; } void find(int x) { //找到一個(gè)合適的徒弟,讓別人拜 if(ve[x].size() < d[x]) {flag = x;return ;}int uu, MAX = -1;for(int i = 0; i < ve[x].size(); i++) {num = 0; //使用dfs前初始為零 int t = dfs(ve[x][i]);if(t > MAX) {MAX = t;uu = ve[x][i];}}find(uu);if(flag)return ; } int main() { // freopen("in.txt", "r", stdin);int n, m;while(scanf("%d %d", &n, &m) != EOF) {for(int i = 1; i <= n; i++)ve[i].clear();memset(tea, 0, sizeof(tea));for(int i = 1; i <= n; i++) {scanf("%d", &d[i]);}for(int i = 0; i < m; i++) {int u, v;scanf("%d %d", &u, &v); // if(tea[u] == v) //題上說:可以重復(fù)拜師,但是取最后一次 // continue; //個(gè)人感覺加上這句話不對(duì) (因?yàn)楹竺娴陌輲?#xff0c;可能影響原來的關(guān)系)//以重復(fù)拜師,結(jié)果可能不一樣.但是這樣也對(duì)。 //各位大佬請(qǐng)解釋。。。if(tea[u]) { vector<int>::iterator it;it = find(ve[tea[u]].begin(), ve[tea[u]].end(), u); ve[tea[u]].erase(it); //解除原來的師徒關(guān)系}if(ve[v].size() < d[v]) { //師傅的徒弟人數(shù)還沒有滿 tea[u] = v;ve[v].push_back(u);}else {flag = 0;find(v);tea[u] = flag;ve[flag].push_back(u);} }for(int i = 1; i <= n; i++) {num = 0; //記得初始為零 int t = dfs(i);printf("%d %d\n", ve[i].size(), t - ve[i].size());}}return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的2262: master(vector + dfs)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。