麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

CCF201509-4 高速公路(100分)

2019-11-14 10:00:37
字體:
供稿:網(wǎng)友

試題編號(hào):201509-4
試題名稱:高速公路
時(shí)間限制:1.0s
內(nèi)存限制:256.0MB
問題描述:問題描述  某國(guó)有n個(gè)城市,為了使得城市間的交通更便利,該國(guó)國(guó)王打算在城市之間修一些高速公路,由于經(jīng)費(fèi)限制,國(guó)王打算第一階段先在部分城市之間修一些單向的高速公路。  現(xiàn)在,大臣們幫國(guó)王擬了一個(gè)修高速公路的計(jì)劃。看了計(jì)劃后,國(guó)王發(fā)現(xiàn),有些城市之間可以通過高速公路直接(不經(jīng)過其他城市)或間接(經(jīng)過一個(gè)或多個(gè)其他城市)到達(dá),而有的卻不能。如果城市A可以通過高速公路到達(dá)城市B,而且城市B也可以通過高速公路到達(dá)城市A,則這兩個(gè)城市被稱為便利城市對(duì)。  國(guó)王想知道,在大臣們給他的計(jì)劃中,有多少個(gè)便利城市對(duì)。輸入格式  輸入的第一行包含兩個(gè)整數(shù)n, m,分別表示城市和單向高速公路的數(shù)量。  接下來m行,每行兩個(gè)整數(shù)a, b,表示城市a有一條單向的高速公路連向城市b。輸出格式  輸出一行,包含一個(gè)整數(shù),表示便利城市對(duì)的數(shù)量。樣例輸入5 51 22 33 44 23 5樣例輸出3樣例說明  城市間的連接如圖所示。有3個(gè)便利城市對(duì),它們分別是(2, 3), (2, 4), (3, 4),請(qǐng)注意(2, 3)和(3, 2)看成同一個(gè)便利城市對(duì)。評(píng)測(cè)用例規(guī)模與約定  前30%的評(píng)測(cè)用例滿足1 ≤ n ≤ 100, 1 ≤ m ≤ 1000;  前60%的評(píng)測(cè)用例滿足1 ≤ n ≤ 1000, 1 ≤ m ≤ 10000;  所有評(píng)測(cè)用例滿足1 ≤ n ≤ 10000, 1 ≤ m ≤ 100000。

問題鏈接:CCF201509試題。

問題描述:(參見上文)。

問題分析:這是一個(gè)強(qiáng)聯(lián)通圖的問題,用Tarjan算法來解決。另外一個(gè)算法是kosaraju算法,也用于解決強(qiáng)聯(lián)通圖問題。

程序說明:本程序采用Tarjan算法。主函數(shù)main()中,創(chuàng)建圖對(duì)象是參數(shù)本應(yīng)該用n,但是提交后出現(xiàn)了運(yùn)行錯(cuò)誤,所有改成n+1。程序通過使用Tarjan算法類(參見以下鏈接)來實(shí)現(xiàn),做了簡(jiǎn)單修改,使用變量ans來存儲(chǔ)結(jié)果,其中增加了中間變量count。

求得強(qiáng)聯(lián)通子圖后,對(duì)于每一個(gè)強(qiáng)聯(lián)通子圖如果有k個(gè)結(jié)點(diǎn),若k>1則強(qiáng)聯(lián)通對(duì)結(jié)點(diǎn)的數(shù)量為k*(k-1)/2,若k=1則為0。

相關(guān)鏈接:Tarjan算法查找強(qiáng)聯(lián)通組件

提交后得100分的C++語言程序如下:

/* CCF201509-4 高速公路  */#include <iostream>#include <list>#include <stack>using namespace std;const int NIL = -1;int ans  = 0;// A class that rePResents an directed graphclass Graph{    int V;    // No. of vertices    list<int> *adj;    // A dynamic array of adjacency lists    // A Recursive DFS based function used by SCC()    void SCCUtil(int u, int disc[], int low[],                 stack<int> *st, bool stackMember[]);public:    Graph(int V);   // Constructor    void addEdge(int v, int w);   // function to add an edge to graph    void SCC();    // prints strongly connected components};Graph::Graph(int V){    this->V = V;    adj = new list<int>[V];}void Graph::addEdge(int v, int w){    adj[v].push_back(w);}// A recursive function that finds and prints strongly connected// components using DFS traversal// u --> The vertex to be visited next// disc[] --> Stores discovery times of visited vertices// low[] -- >> earliest visited vertex (the vertex with minimum//             discovery time) that can be reached from subtree//             rooted with current vertex// *st -- >> To store all the connected ancestors (could be part//           of SCC)// stackMember[] --> bit/index array for faster check whether//                  a node is in stackvoid Graph::SCCUtil(int u, int disc[], int low[], stack<int> *st,                    bool stackMember[]){    // A static variable is used for simplicity, we can avoid use    // of static variable by passing a pointer.    static int time = 0;    // Initialize discovery time and low value    disc[u] = low[u] = ++time;    st->push(u);    stackMember[u] = true;    // Go through all vertices adjacent to this    list<int>::iterator i;    for (i = adj[u].begin(); i != adj[u].end(); ++i)    {        int v = *i;  // v is current adjacent of 'u'        // If v is not visited yet, then recur for it        if (disc[v] == -1)        {            SCCUtil(v, disc, low, st, stackMember);            // Check if the subtree rooted with 'v' has a            // connection to one of the ancestors of 'u'            // Case 1 (per above discussion on Disc and Low value)            low[u]  = min(low[u], low[v]);        }        // Update low value of 'u' only of 'v' is still in stack        // (i.e. it's a back edge, not cross edge).        // Case 2 (per above discussion on Disc and Low value)        else if (stackMember[v] == true)            low[u]  = min(low[u], disc[v]);    }    // head node found, pop the stack and print an SCC    int w = 0;  // To store stack extracted vertices    int count = 0;    if (low[u] == disc[u])    {        while (st->top() != u)        {            w = (int) st->top();//            cout << w << " ";            count++;            stackMember[w] = false;            st->pop();        }        w = (int) st->top();//        cout << w << "/n";        count++;        stackMember[w] = false;        st->pop();    }    if(count > 1)        ans += count * (count -1) / 2;}// The function to do DFS traversal. It uses SCCUtil()void Graph::SCC(){    int *disc = new int[V];    int *low = new int[V];    bool *stackMember = new bool[V];    stack<int> *st = new stack<int>();    // Initialize disc and low, and stackMember arrays    for (int i = 0; i < V; i++)    {        disc[i] = NIL;        low[i] = NIL;        stackMember[i] = false;    }    // Call the recursive helper function to find strongly    // connected components in DFS tree with vertex 'i'    for (int i = 0; i < V; i++)        if (disc[i] == NIL)            SCCUtil(i, disc, low, st, stackMember);}int main(){    int n, m, src, dest;    cin >> n >> m;    Graph g(n+1);    for(int i=1; i<=m; i++) {        cin >> src >> dest;        g.addEdge(src, dest);    }    g.SCC();    cout << ans << endl;    return 0;}


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美亚洲一区二区三区四区 | 九九热精品在线视频 | 成人毛片一区 | 久久精品2019中文字幕 | 久久99国产精品免费网站 | www日韩大片 | av电影在线观看网站 | 99精品视频在线免费观看 | av影片在线观看 | 天天操很很操 | 日韩在线毛片 | 综合网日日天干夜夜久久 | 免费高清一级欧美片在线观看 | 免费日本一区二区 | 精品国产一区二区三区在线观看 | 国产一区视频观看 | 羞羞视频免费网站男男 | 久久婷婷一区二区三区 | 九一免费国产 | 成人精品aaaa网站 | 在线成人精品视频 | a视频在线免费观看 | 综合网日日天干夜夜久久 | 久久蜜桃香蕉精品一区二区三区 | 成码无人av片在线观看网站 | 亚洲欧美成aⅴ人在线观看 免费看欧美黑人毛片 | 国产成年人视频网站 | 欧美1区2区在线观看 | 午夜啪视频| 欧美无限资源 | 一级做a爱片性色毛片 | 99999久久久久久 | 国产免费激情视频 | 中文字幕一区二区三区久久 | 欧美18一19sex性护士农村 | 欧美hdfree性xxxx | 亚洲成人精品视频 | 免费看a级片 | 欧美精品免费一区二区三区 | 免费看成人av | 国产精品性夜天天视频 |