hdu1827Summer Holiday

来源:互联网 发布:成人频道直播软件 编辑:程序博客网 时间:2024/05/18 11:27

思路:求强连通分量,然后求缩点之后入度为零的个数。此代码没缩点,用的Kosaraju算法,然后在反图上找。

Summer Holiday

Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1270    Accepted Submission(s): 575

Problem Description
To see a World in a Grain of Sand 
And a Heaven in a Wild Flower, 
Hold Infinity in the palm of your hand 
And Eternity in an hour. 
                  —— William Blake

听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗?
 
Input
多组测试数组,以EOF结束。
第一行两个整数N和M(1<=N<=1000, 1<=M<=2000),表示人数和联系对数。
接下一行有N个整数,表示Wiskey联系第i个人的电话费用。
接着有M行,每行有两个整数X,Y,表示X能联系到Y,但是不表示Y也能联系X。
 
Output
输出最小联系人数和最小花费。
每个CASE输出答案一行。
 
Sample Input
12 162 2 2 2 2 2 2 2 2 2 2 2 1 33 22 13 42 43 55 44 66 47 47 127 88 78 910 911 10
 

Sample Output
3 6
 
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <stack>#define DEBUGconst int INF = 0x7fffffff;using namespace std;const int maxn = 1000+10;//Accepted1827343MS532K2695 BG++Achiberxvector<int> G[maxn], G2[maxn];vector<int> S;int vis[maxn], sccno[maxn], scc_cnt;int cost[maxn];// the cost of every node.int gn, gm; int minv[maxn];// init INF; int number; // record the number of degree is 0.void dfs1(int u) {    if(vis[u]) return;    vis[u] = 1;    for(int i = 0; i < (int)G[u].size(); i++) dfs1(G[u][i]);    S.push_back(u);}void dfs2(int u) {    if(sccno[u]) return;    sccno[u] = scc_cnt;    for(int i = 0; i < (int)G2[u].size(); i++) dfs2(G2[u][i]);}void find_scc(int n) {    scc_cnt = 0;    S.clear();    memset(sccno, 0, sizeof(sccno));    memset(vis, 0, sizeof(vis));    for(int i = 1; i <= gn; i++) dfs1(i);    for(int i = n-1; i >= 0; i--) {        if(!sccno[S[i]]) {            scc_cnt++;            dfs2(S[i]);        }    }}void build_map() {    for(int i = 0; i < maxn; i++) {        G[i].clear(); G2[i].clear();    }    int u, v;    for(int i = 1; i <= gm; i++) {        scanf("%d%d", &u, &v); // directed graph.        G[u].push_back(v);        G2[v].push_back(u);    }}#ifndef DEBUGvoid mid_res() {    for(int i = 1; i <= gn; i++) {        printf("sccno[%d] = %d\n", i, sccno[i]);    }    cout << endl;}#endifint work() {    bool tag[maxn];    memset(tag, false, sizeof(tag));    for(int i = 1; i <= gn; i++) {        if(tag[sccno[i]]) continue; // outdegree != 0.        for(int j = 0; j < (int)G2[i].size(); j++) {            if(sccno[i] != sccno[G2[i][j]]) {                tag[sccno[i]] = true; //  reverse graph outdegree > 0.                break;            }        }    }    vector<int> ss;    ss.clear();    for(int i = 0; i < maxn; i++) minv[i] = INF;//init.    for(int i = 1; i <= scc_cnt; i++) {        if(tag[i] == false) {            ss.push_back(i);        }    }    number = ss.size();    int total = 0;    for(int i = 0; i < (int)ss.size(); i++) {        for(int j = 1; j <= gn; j++) {            if(sccno[j] == ss[i]) {                minv[i] = min(cost[j], minv[i]);            }        }        total += minv[i];    }    return total;}int main(){    while(scanf("%d%d", &gn, &gm) != EOF) {        for(int i = 1; i <= gn; i++) {            scanf("%d", &cost[i]);        }        build_map();        find_scc(gn);       // mid_res();        int total = work();        printf("%d %d\n", number, total);    }    return 0;}

原创粉丝点击