BestCoder Round #1


    今天開始去做BC 的AB 就像和CF 的ABC 一樣吧,後面的題目,有能力也儘量去做做、、、

    附上今天在羣裏羣巨發的一條鏈接,可以去看看、、如何成爲阿里巴巴算法工程師? - 計算機 - 知乎

    

逃生



Problem Description
糟糕的事情發生啦,現在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

現在有n個人,從1標號到n。同時有一些奇怪的約束條件,每個都形如:a必須在b之前。
同時,社會是不平等的,這些人有的窮有的富。1號最富,2號第二富,以此類推。有錢人就賄賂負責人,所以他們有一些好處。

負責人現在可以安排大家排隊的順序,由於收了好處,所以他要讓1號儘量靠前,如果此時還有多種情況,就再讓2號儘量靠前,如果還有多種情況,就讓3號儘量靠前,以此類推。

那麼你就要安排大家的順序。我們保證一定有解。
 

Input
第一行一個整數T(1 <= T <= 5),表示測試數據的個數。
然後對於每個測試數據,第一行有兩個整數n(1 <= n <= 30000)和m(1 <= m <= 100000),分別表示人數和約束的個數。

然後m行,每行兩個整數a和b,表示有一個約束a號必須在b號之前。a和b必然不同。
 

Output
對每個測試數據,輸出一行排隊的順序,用空格隔開。
 

Sample Input
1 5 10 3 5 1 4 2 5 1 2 3 4 1 4 2 3 1 5 3 5 1 2
 

Sample Output
1 2 3 4 5
 

    這是一道拓撲排序的題目,我一開始以爲是模版題了,敲了一下,先是用的鄰接矩陣,果斷超內存了30000*30000的數組、、、然後用的vector和for循環,在敲完之前,我也已經預料到可能會超時的,結果、、、然後我去百度了下,發現我題目要求就沒搞清楚了!最後看了他們的方法,是優先隊列+ 拓撲排序,處理方法也是比較好的、、

    

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

#define N 30010

vector<int>mpt[N];
int in[N];
int n, m;

int main()
{
    int a, b;
    int t;
    while(~scanf("%d",&t))
    {
        while(t --)
        {
            scanf("%d%d",&n,&m);
            memset(in, 0, sizeof(in));

            for(int i = 1; i <= n; i ++)
            {
                mpt[i].clear();
            }

            for(int i = 0; i < m; i ++)
            {
                scanf("%d%d",&a,&b);
                in[a] ++;
                mpt[b].push_back(a);
            }

            priority_queue<int> qe;
            vector<int> ans;

            for(int i = 1; i <= n; i ++)
            {
                if(in[i] == 0)
                qe.push(i);
            }

            while(!qe.empty())
            {
                int k = qe.top();
                ans.push_back(k);
                qe.pop();
                for(int i = 0; i < mpt[k].size(); i ++)
                {
                    int v = mpt[k][i];
                    in[v] --;
                    if(in[v] == 0)
                        qe.push(v);
                }
            }
            for(int i = ans.size() - 1; i > 0; i --)
            {
                printf("%d ",ans[i]);
            }
            printf("%d\n",ans[0]);
        }
    }
    return 0;
}

項目管理


Problem Description
我們建造了一個大項目!這個項目有n個節點,用很多邊連接起來,並且這個項目是連通的!
兩個節點間可能有多條邊,不過一條邊的兩端必然是不同的節點。
每個節點都有一個能量值。

現在我們要編寫一個項目管理軟件,這個軟件呢有兩個操作:
1.給某個項目的能量值加上一個特定值。
2.詢問跟一個項目相鄰的項目的能量值之和。(如果有多條邊就算多次,比如a和b有2條邊,那麼詢問a的時候b的權值算2次)。
 

Input
第一行一個整數T(1 <= T <= 3),表示測試數據的個數。
然後對於每個測試數據,第一行有兩個整數n(1 <= n <= 100000)和m(1 <= m <= n + 10),分別表示點數和邊數。

然後m行,每行兩個數a和b,表示a和b之間有一條邊。
然後一個整數Q。

然後Q行,每行第一個數cmd表示操作類型。如果cmd爲0,那麼接下來兩個數u v表示給項目u的能量值加上v(0 <= v <= 100)。
如果cmd爲1,那麼接下來一個數u表示詢問u相鄰的項目的能量值之和。

所有點從1到n標號。
 

Output
對每個詢問,輸出一行表示答案。
 

Sample Input
1 3 2 1 2 1 3 6 0 1 15 0 3 4 1 1 1 3 0 2 33 1 2
 

Sample Output
4 15 15
  

    中文題,也不用解釋題意了 - -# . 暴力過的,不過題解說是有關圖的,有優化版,下次補上、、、 然後現在大一點的數據,多維數組也不敢開了,不知道可不可以一直用着stl,其實我也不知道stl 優化在哪裏 - -#

    

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

#define N 100010

vector<int> ve[N];
int sum[N];
int n, m;

int main()
{
    int t, q;
    int a, b;
    int qq, v, u;
    while(~scanf("%d",&t))
    {
        while(t --)
        {
            scanf("%d%d",&n,&m);

            for(int i = 0; i <= n; i ++)
            {
                ve[i].clear();
            }
            memset(sum , 0, sizeof(sum));
            for(int i = 0; i < m; i ++)
            {
                scanf("%d%d",&a,&b);
                ve[a].push_back(b);
                ve[b].push_back(a);
            }
            scanf("%d",&qq);
            while(qq --)
            {
                scanf("%d",&q);
                if(q == 0)
                {
                    scanf("%d%d",&u,&v);
                    sum[u] += v;
                }
                else
                {
                    scanf("%d",&u);
                    int ans = 0;
                    for(int i = 0; i < ve[u].size(); i ++)
                    {
                        ans += sum[ve[u][i]];
                    }
                    printf("%d\n",ans);
                }
            }
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章