UVA11324 The Largest Clique
很自然的想到先tarjan把强联通分量缩点,因为对于一个强联通分量,要么不选,要么全选,所以可看成一个点。
然后转化成了求DAG上的一条最长路(每一个点都有权值)。刚开始我想用dijkstra写:先把所入度为0的点都放进优先队列里,然后跑dijkstra,把所有的小于号改成大于号。
结果就WA了。
想了好半天,发现不能用dijkstra求。这和负权一样:u已经被更新了,但可能还有一条节点数很多的路径到达点u,而这个答案比当前的优,却因为u已经进过队列而更新不了。
所以只能dp。这个dp那是相当水,假设有一条边(u->v), 则dp[v] = max(dp[v], dp[u] + val[v])。然后我们从所有入度为0的点开始dp就妥了。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e4 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, m;
vector<int> v[maxn]; stack<int> st;
bool in[maxn];
int dfn[maxn], low[maxn], cnt = ;
int col[maxn], val[maxn], ccol = ;
void tarjan(int now)
{
dfn[now] = low[now] = ++cnt;
st.push(now); in[now] = ;
for(int i = ; i < (int)v[now].size(); ++i)
{
if(!dfn[v[now][i]])
{
tarjan(v[now][i]);
low[now] = min(low[now], low[v[now][i]]);
}
else if(in[v[now][i]]) low[now] = min(low[now], dfn[v[now][i]]);
}
if(dfn[now] == low[now])
{
int x; ccol++;
do
{
x = st.top(); st.pop();
in[x] = ;
col[x] = ccol;
val[ccol]++; }while(x != now);
}
} vector<int> v2[maxn];
int du[maxn];
void newGraph(int now)
{
int u = col[now];
for(int i = ; i < (int)v[now].size(); ++i)
{
int e = col[v[now][i]];
if(u == e) continue;
v2[u].push_back(e);
du[e]++;
}
} int dis[maxn];
void dp(int now)
{
for(int i = ; i < (int)v2[now].size(); ++i)
{
if(dis[v2[now][i]] < dis[now] + val[v2[now][i]]) //算一个剪枝吧
{
dis[v2[now][i]] = dis[now] + val[v2[now][i]];
dp(v2[now][i]);
}
}
} void init()
{
for(int i = ; i < maxn; ++i) {v[i].clear(); v2[i].clear();}
while(!st.empty()) st.pop();
Mem(dfn, ); Mem(low, ); Mem(col, ); Mem(val, );
cnt = ccol = ;
Mem(du, ); Mem(dis, );
} int main()
{
int T = read();
while(T--)
{
init();
n = read(); m = read();
for(int i = ; i <= m; ++i)
{
int x = read(), y = read();
v[x].push_back(y);
}
for(int i = ; i <= n; ++i) if(!dfn[i]) tarjan(i);
for(int i = ; i <= n; ++i) newGraph(i);
for(int i = ; i <= ccol; ++i) if(!du[i]) dis[i] = val[i], dp(i);
int ans = ;
for(int i = ; i <= ccol; ++i) ans = max(ans, dis[i]);
write(ans); enter;
}
return ;
}
UVA11324 The Largest Clique的更多相关文章
- UVA11324 The Largest Clique[强连通分量 缩点 DP]
UVA - 11324 The Largest Clique 题意:求一个节点数最大的节点集,使任意两个节点至少从一个可以到另一个 同一个SCC要选一定全选 求SCC 缩点建一个新图得到一个DAG,直 ...
- 『题解』UVa11324 The Largest Clique
原文地址 Problem Portal Portal1:UVa Portal2:Luogu Portal3:Vjudge Description Given a directed graph \(\t ...
- UVA11324 The Largest Clique —— 强连通分量 + 缩点 + DP
题目链接:https://vjudge.net/problem/UVA-11324 题解: 题意:给出一张有向图,求一个结点数最大的结点集,使得任意两个结点u.v,要么u能到达v, 要么v能到达u(u ...
- UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)
题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...
- uva11324 The Largest Clique --- 强连通+dp
给一个有向图G,求一个子图要求当中随意两点至少有一边可达. 问这个子图中最多含多少个顶点. 首先找SCC缩点建图.每一个点的权值就是该点包括点的个数. 要求当中随意两点可达,实际上全部边仅仅能同方向, ...
- UVA11324 The Largest Clique(DP+缩点)
题意:给一张有向图G,求一个结点数最大的结点集,使得该结点中任意两个结点 u 和 v满足:要么 u 可以到达 v, 要么 v 可以到达 u(u 和 v 相互可达也可以). 分析:”同一个强连通分量中的 ...
- UVA11324 The Largest Clique (强连通缩点+DP最长路)
<题目链接> 题目大意: 给你一张有向图 G,求一个结点数最大的结点集,使得该结点集中的任意两个结点 u 和 v 满足:要么 u 可以达 v,要么 v 可以达 u(u,v相互可达也行). ...
- UVA-11324 The Largest Clique (强连通+DP)
题目大意:在一张无向图中,最大的节点集使得集合内任意两个节点都能到达对方. 题目分析:找出所有的强连通分量,将每一个分量视作大节点,则原图变成了一张DAG.将每个分量中的节点个数作为节点权值,题目便转 ...
- 【UVA11324】 The Largest Clique (Tarjan+topsort/记忆化搜索)
UVA11324 The Largest Clique 题目描述 给你一张有向图 \(G\),求一个结点数最大的结点集,使得该结点集中的任意两个结点 \(u\) 和 \(v\) 满足:要么 \(u\) ...
随机推荐
- Html-完整表格
表头th 特殊的单元格:加粗.居中 它的用户是取代td的位置即可 <table border="2"> <tr> <th>姓名</th&g ...
- RabbitMQ---1、安装与部署
一.下载资源 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装Rabbit MQ的前提是安装Erlang.(在官网自行选择版本) 1.otp_win64_20.2.exe 下载地 ...
- 从BASE理论到CAP理论
BASE理论面向的是大型高可用可扩展的分布式系统,和传统事务的CID特性是相反的,它完全不同于ACID的强一致性模型,而是提出通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到 ...
- python学习之老男孩python全栈第九期_day026知识点总结——封装、property、类方法、初识反射
一. 封装 class Room: def __init__(self, name, length, width): self.__name = name self.__length = length ...
- ES6学习笔记(四)-数值扩展
PS: 前段时间转入有道云笔记,体验非常友好,所以笔记一般记录于云笔记中,每隔一段时间,会整理一下, 发在博客上与大家一起分享,交流和学习. 以下:
- SJ定理——省选前的学习2
——博弈论?上SG定理!什么?不行?那就SJ定理吧. 原来还有这么个玩意... bzoj1022. 大意是Nim取石子游戏中取到最后一个石子就算输,即无法取了就获胜(原版是无法取了就输). 我们试图套 ...
- layui-open-上传文件
<!--选择文件上传--> <script id="upload_file_dialog" type="text/html"> < ...
- 微信小程序-view组件
<view class="section"> <view class="section__title">flex-direction: ...
- log4net.dll添加报错
描述: 新建项目Log4Net类库项目,添加log4net.dll,封装Log类对日志进行操作 新建webForm项目添加Log4Net类库生成的dll生成日志,页面报错,未能加载文件或程序集log4 ...
- javascript的时间描述图怎么写
在gis系统中往往需要在一个时间间隔内把图形动态播放出来,比如2000年到现在地震变化啊,海啸的变化,在flex中这种展现方式需要后台rest服务相结合,要建立有时间点的图层,arcgis发布要选ti ...