码迷,mamicode.com
首页 > 其他好文 > 详细

HDU-1827 Summer Holiday

时间:2017-05-20 22:40:07      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:des   mat   最小花费   for   stack   rip   ini   整数   out   

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 16
2 2 2 2 2 2 2 2 2 2 2 2 
1 3
3 2
2 1
3 4
2 4
3 5
5 4
4 6
6 4
7 4
7 12
7 8
8 7
8 9
10 9
11 10
Sample Output
3 6

 

求最小点基和最小权点基稞题。

①找出图G的所有强连通分量。

②从强连通分量中找出所有的最高强连通分量。也就是缩点后入度为0的点。

③从每个最高强连通分量中任取一点,组成点集B就是一个最小点基。

从每个最高强连通分量中取权值最小的点,组成点集B就是一个最小点权基。

 

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define file(a) freopen(a".in","r",stdin); freopen(a".out","w",stdout);

inline int gi()
{
    bool b=0; int r=0; char c=getchar();
    while(c<0 || c>9) { if(c==-) b=!b; c=getchar(); }
    while(c>=0 && c<=9) { r=r*10+c-0; c=getchar(); }
    if(b) return -r; return r;
}

const int inf = 1e9+7, N = 1007, M = 2007;
int n,m,num,cnt,Deep,f[N],dfn[N],low[N],bl[N],V[N],C[N],rd[N];
bool b[N];
stack <int> s;
struct data
{
    int fr,nx,to;
}da[M];

inline void add (int fr,int to)
{
    da[++num].fr=fr, da[num].to=to, da[num].nx=f[fr], f[fr]=num;
}

inline void tarjan (int o)
{
    int i,to;
    dfn[o]=low[o]=++Deep;
    s.push(o); b[o]=1;
    for (i=f[o]; i; i=da[i].nx)
        {
            to=da[i].to;
            if (!dfn[to]) tarjan (to), low[o]=min(low[o],low[to]);
            else if (b[to]) low[o]=min(low[o],dfn[to]);
        }
    if (low[o] == dfn[o])
        {
            cnt++;
            do
                {
                    to=s.top(); s.pop(); b[to]=0;
                    bl[to]=cnt; V[cnt]=min(V[cnt],C[to]);
                }
            while(to != o);
        }
}

int main()
{
//    file("HDU-1827");
    int i,x,y;
    while (scanf ("%d%d",&n,&m) != EOF)
        {
            for (i=1; i<=n; i++) C[i]=gi(), V[i]=inf;
            for (i=1; i<=m; i++)
                {
                    x=gi(), y=gi();
                    add (x,y);
                }
            for (i=1; i<=n; i++) if(!dfn[i]) tarjan (i);
            for (i=1; i<=num; i++)
                {
                    x=bl[da[i].fr], y=bl[da[i].to];
                    if (x != y) rd[y]++;
                }
            x=0, y=0;
            for (i=1; i<=cnt; i++) if (!rd[i]) x++, y+=V[i];
            printf ("%d %d\n",x,y);
            for (i=1; i<=n; i++) f[i]=C[i]=V[i]=dfn[i]=low[i]=bl[i]=0;
            for (i=1; i<=cnt; i++) rd[i]=0;
            for (i=1; i<=num; i++) da[i]={ 0,0,0 };
            num=Deep=cnt=0;
        }
    return 0;
}

 

欢迎在评论区提问质疑!

HDU-1827 Summer Holiday

标签:des   mat   最小花费   for   stack   rip   ini   整数   out   

原文地址:http://www.cnblogs.com/y142857/p/6883316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!