链接: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;
}

  

最新文章

  1. JavaScript Date对象
  2. nginx的ngx_http_request_t结构体
  3. bzoj 3518 Dirichlet卷积
  4. SQL Server case表达式的用法
  5. {CSDN}{英雄会}{砍树、石子游戏}
  6. 九度OJ题目1387斐波那契数列
  7. Windows系统上如何使用SSH
  8. NoSQL 数据库系统对比
  9. 一道movfuscator混淆过的简单逆向
  10. 解决外贸电商难题,PayPal中国外贸电商大会圆满礼成
  11. openwrt的默认/etc/config/network文件是如何生成的?
  12. 门面模式(Facade)解析
  13. 《JavaScript高级程序设计》笔记二
  14. 和为S的连续正数序列——牛客网(剑指offer)
  15. 网络协议 终章 - GTP 协议:复杂的移动网络
  16. Lab 11-3
  17. Android studio 3.1.2报错,no target device found
  18. Postman 使用技巧之多环境测试及接口依赖关系处理
  19. while(scanf(&quot;%d %d&quot;,&amp;a,&amp;b)!=EOF)
  20. ajax基本原理

热门文章

  1. Win7、Win8、Win10始终以管理员身份运行程序。
  2. 分享知识-快乐自己:Hibernate 中Criteria Query查询详解
  3. python学习笔记:第五天( 列表、元组)
  4. VC++动态链接库(DLL)编程深入浅出:Q&amp;A(原创)
  5. 苹果手机app试玩平台汇总--手机链接入口
  6. unicode和utf-8互转
  7. source和sh执行脚本时的差异
  8. Python 查看本机WiFi密码
  9. &lt;正则吃饺子&gt; :关于redis配置文件参数详解
  10. MFC中界面自适应