HDU-3072-IntelligenceSystem(tarjan,贪心)

链接:https://vjudge.net/problem/HDU-3072

题意:

给你n个点,1个点到另一个点连接花费c,但是如果几个点可以相互可达,则这几个点连通花费为0.

求将整个图连通的最小花费。

思路:

tarjan,求出强连通子图。

对每个子图的进点的最小值更新,再累加即可,(不过不知道为什么)

代码:

#include <iostream>
#include <memory.h>
#include <string>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
#include <cstdio>
#include <set>
#include <iterator>
#include <cstring>
using namespace std;

typedef long long LL;
const int MAXN = 5e4+10;
const int INF = 0x3f3f3f3f;

struct Node
{
    int from_, to_, value_;
    Node(int from, int to, int value):from_(from), to_(to), value_(value){}
    bool operator < (const Node &that) const
    {
        return this->value_ > that.value_;
    }
};

vector<Node> G[MAXN];
stack<int> St;
int Dfn[MAXN], Low[MAXN];
int Vis[MAXN], Dis[MAXN];
int Fa[MAXN], Val[MAXN];
int Num[MAXN];
int n, m;
int times, cnt;

void Init()
{
    for (int i = 1;i <= n;i++)
        G[i].clear(), Fa[i] = i;
    memset(Dfn, 0, sizeof(Dfn));
    memset(Low, 0, sizeof(Low));
    memset(Vis, 0, sizeof(Vis));
    memset(Dis, 0, sizeof(Dis));
    memset(Num, 0, sizeof(Num));
    memset(Val, 0, sizeof(Val));
    times = cnt = 0;
}

void Tarjan(int x)
{
    Dfn[x] = Low[x] = ++times;
    Vis[x] = 1;
    St.push(x);
    for (int i = 0;i < G[x].size();i++)
    {
        int node = G[x][i].to_;
        if (Dfn[node] == 0)
        {
            Tarjan(node);
            Low[x] = min(Low[x], Low[node]);
        }
        else if (Vis[node] == 1)
            Low[x] = min(Low[x], Dfn[node]);
    }
    if (Low[x] == Dfn[x])
    {
        cnt++;
        Num[cnt] = 0;
        while (St.top() != x)
        {
            Num[cnt]++;
            Fa[St.top()] = cnt;
            Vis[St.top()] = 0;
            St.pop();
        }
        Num[cnt]++;
        Fa[St.top()] = cnt;
        Vis[St.top()] = 0;
        St.pop();
    }
}

int main()
{
    int t, cn = 0;
    while (~scanf("%d%d", &n, &m))
    {
        Init();
        int l, r, v;
        for (int i = 1;i <= m;i++)
        {
            scanf("%d%d%d", &l, &r, &v);
            l++, r++;
            G[l].emplace_back(l, r, v);
        }
        for (int i = 1;i <= n;++i)
            if (!Dfn[i])
                Tarjan(i);
        for (int i = 1;i <= cnt;i++)
            Val[i] = INF;
        for (int i = 1;i <= n;i++)
        {
            for (int j = 0;j < G[i].size();j++)
            {
                int node = G[i][j].to_;
                if (Fa[i] != Fa[node])
                    Val[Fa[node]] = min(Val[Fa[node]], G[i][j].value_);
            }
        }
        int res = 0;
        for (int i = 1;i <= cnt;i++)
            if (Val[i] != INF)
                res += Val[i];
        cout << res << endl;
    }

    return 0;
}

  

原文地址:https://www.cnblogs.com/YDDDD/p/10822851.html

时间: 2024-10-18 02:00:54

HDU-3072-IntelligenceSystem(tarjan,贪心)的相关文章

HDU 3072 Intelligence System (强连通分量)

题目地址:HDU 3072 这题一开始理解错题目意思了..(不得不吐槽一下题目意思确实不好理解..)用的强连通+最小生成树做的...然后错了好多遍...sad..题目意思是从一个给定点向其他所有点通信的最少花费,那么入度为0的点肯定是那个给定点.然后对于其它点,枚举就好了.找一个到他花费最少的点的花费. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue&g

hdu 3072 有向图缩点成最小树形图计算最小权

题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新记录最小到达该连通分量的最小边权即可...边聊天,边1A,哈哈... #include<iostream> #include<stack> #include<queue> #include<cstdio> #include<cstring> usin

hdu 4296 Buildings(贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4296 Buildings Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1822    Accepted Submission(s): 722 Problem Description Have you ever heard the sto

hdu 4864 Task (贪心)

# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; struct node { int t; int v; int yy; }; struct node a[100010],b[100010]; bool cmp(node a1,node a2) { if(a1.t==a2.t)//先按时间从大到小 return a1.v>a2.v;//再按水平从大

HDU 5014 Number Sequence 贪心 2014 ACM/ICPC Asia Regional Xi&#39;an Online

尽可能凑2^x-1 #include <cstdio> #include <cstring> const int N = 100005; int a[N], p[N]; int init(int x) { int cnt = 0; while(x > 1) { x /= 2; cnt ++; } return cnt + 1; } int main() { int n; while(~scanf("%d", &n)){ for(int i = 0;

HDU 4903 (模拟+贪心)

Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a heat for years in China. The game goes with the 54 poker cards for 3 players, where the “Landlord” has 20 cards and the other two (the “Farmers”) have 1

HDU 1045 Fire Net 贪心

Problem Description Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle that has four openings through wh

Intelligence System HDU - 3072(强连通分量)

Intelligence System HDU - 3072 题意:一个人要传递命令给所有人,如果两人之间互达,不需任何费用,求最少费用 有向图强连通. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxv=50010; 5 const int maxe=100010; 6 int n,m; 7 struct Edge{ 8 int u,v,w; 9 int

HDU 1338 Game Prediction 贪心

Problem Description Suppose there are M people, including you, playing a special card game. At the beginning, each player receives N cards. The pip of a card is a positive integer which is at most N*M. And there are no two cards with the same pip. Du

hdu 1009 FatMouse&#39; Trade(贪心)

题目来源:hdu 1009 FatMouse' Trade FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 54581 Accepted Submission(s): 18299 Problem Description FatMouse prepared M pounds of cat food, ready