嘟嘟嘟

很自然的想到先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的更多相关文章

  1. UVA11324 The Largest Clique[强连通分量 缩点 DP]

    UVA - 11324 The Largest Clique 题意:求一个节点数最大的节点集,使任意两个节点至少从一个可以到另一个 同一个SCC要选一定全选 求SCC 缩点建一个新图得到一个DAG,直 ...

  2. 『题解』UVa11324 The Largest Clique

    原文地址 Problem Portal Portal1:UVa Portal2:Luogu Portal3:Vjudge Description Given a directed graph \(\t ...

  3. UVA11324 The Largest Clique —— 强连通分量 + 缩点 + DP

    题目链接:https://vjudge.net/problem/UVA-11324 题解: 题意:给出一张有向图,求一个结点数最大的结点集,使得任意两个结点u.v,要么u能到达v, 要么v能到达u(u ...

  4. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...

  5. uva11324 The Largest Clique --- 强连通+dp

    给一个有向图G,求一个子图要求当中随意两点至少有一边可达. 问这个子图中最多含多少个顶点. 首先找SCC缩点建图.每一个点的权值就是该点包括点的个数. 要求当中随意两点可达,实际上全部边仅仅能同方向, ...

  6. UVA11324 The Largest Clique(DP+缩点)

    题意:给一张有向图G,求一个结点数最大的结点集,使得该结点中任意两个结点 u 和 v满足:要么 u 可以到达 v, 要么 v 可以到达 u(u 和 v 相互可达也可以). 分析:”同一个强连通分量中的 ...

  7. UVA11324 The Largest Clique (强连通缩点+DP最长路)

    <题目链接> 题目大意: 给你一张有向图 G,求一个结点数最大的结点集,使得该结点集中的任意两个结点 u 和 v 满足:要么 u 可以达 v,要么 v 可以达 u(u,v相互可达也行). ...

  8. UVA-11324 The Largest Clique (强连通+DP)

    题目大意:在一张无向图中,最大的节点集使得集合内任意两个节点都能到达对方. 题目分析:找出所有的强连通分量,将每一个分量视作大节点,则原图变成了一张DAG.将每个分量中的节点个数作为节点权值,题目便转 ...

  9. 【UVA11324】 The Largest Clique (Tarjan+topsort/记忆化搜索)

    UVA11324 The Largest Clique 题目描述 给你一张有向图 \(G\),求一个结点数最大的结点集,使得该结点集中的任意两个结点 \(u\) 和 \(v\) 满足:要么 \(u\) ...

随机推荐

  1. 如鹏网学习笔记(十四)ASP.NET

    Asp.net笔记 一.Socket类 进行网络编程的类,可以在两台计算机之间进行网络通讯 过程: 向服务器发送指令: GET /index.html HTTP/1.1 Host:127.0.0.1: ...

  2. 在Ubuntu16.04.4和Windows10上安装jdk

    在Ubuntu16.04.4和Windows10上安装jdk 一.在Ubuntu16.04.4上安装jdk  1.下载jdk安装包     首先我们在oracle官网上下载jdk-8u161-linu ...

  3. [C#]LockBits使用笔记

    昨天想基于一张图片做个手机锁屏来着,原图如下:主要是嫌白底太丑了,一开始是想画图工具直接油漆桶伺候,然而一浇上去就发现问题了,变成了这样:看来得手工处理一下把底色统一了,原图分辨率挺高的,SetPix ...

  4. win下gosublime配置ctag

    ctags(Generate tag files for source code)是vim下方便代码阅读的工具.尽管ctags也可以支持其它编辑器,但是它正式支持的只有VIM.并且VIM中已经默认安装 ...

  5. LocalStorage和sessionStorage之间的区别

    众所周知,自从HTML 5 标准出现之后,本地化存储一度成为热搜的关键词.在HTML 5 最开始时,本地存储有两种方式:一种是web Storage,另一种是web SQL.由于web SQL的实现是 ...

  6. 【Codeforces】Helvetic Coding Contest 2017 online mirror比赛记

    第一次打ACM赛制的团队赛,感觉还行: 好吧主要是切水题: 开场先挑着做五道EASY,他们分给我D题,woc什么玩意,还泊松分布,我连题都读不懂好吗! 果断弃掉了,换了M和J,然后切掉了,看N题: l ...

  7. Storage 的使用

    //是否不支持storage isNoStorage: function(){ if(typeof(Storage)=="function" || window.sessionSt ...

  8. String class fetch functionality

    String类的获取功能: package com.itheima_04; /* * String类的获取功能: * int length():获取字符串的长度,其实也就是字符个数 * char ch ...

  9. python oop常用术语 继承 多态 封装

    面向对象优点 1.通过封装明确了内外 2.通过继承+多态在语言层面支持了归一化设计 抽象/实现 抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于 绘程序结构,从而实现 ...

  10. 媒体查询hack

    随着Responsive设计的流行,Medial Queries可算是越来越让人观注了.他可以让Web前端工程实现不同设备下的样式选择,让站点在不同的设备中实现不同的效果.这个早前在 w3cplus已 ...