白书上的例题

做一遍tarjan后,缩点,每一个scc节点的权为它的结点数,做一次DAG上的动规,求出路径上的最大点权和,就可以了

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std; const int maxn = ;
int n,m;
int first[maxn];
int sc[maxn],scn[maxn],low[maxn],pre[maxn];
int scnt,ecnt,dfs_clock;
int dp[maxn]; int first1[maxn];
int ecnt1; struct Edge{
int v,next;
}e[maxn*]; Edge e1[maxn*]; stack<int> S; void init(){
ecnt = ecnt1 = ;
memset(first,-,sizeof(first));
memset(first1,-,sizeof(first1));
memset(dp,,sizeof(dp));
} void addedges(int u,int v){
e[ecnt].v = v;
e[ecnt].next = first[u];
first[u] = ecnt++;
} void addedges1(int u,int v){
e1[ecnt1].v = v;
e1[ecnt1].next = first1[u];
first1[u] = ecnt1++;
} void dfs(int u){
low[u] = pre[u] = ++dfs_clock;
S.push(u);
for(int i = first[u];~i;i = e[i].next){
int v = e[i].v;
if(!pre[v]){
dfs(v);
low[u] = min(low[u],low[v]);
}
else if(!sc[v]) low[u] = min(low[u],pre[v]);
}
if(pre[u] == low[u]){
scnt++;
for(;;){
int x = S.top();S.pop();
sc[x] = scnt;
scn[scnt]++;
if(x == u) break;
}
}
} void find_scc(){
while(!S.empty()) S.pop();
scnt = dfs_clock = ;
memset(low,,sizeof(low));memset(pre,,sizeof(pre));
memset(sc,,sizeof(sc));memset(scn,,sizeof(scn)); for(int i = ;i <= n;i++) if(!pre[i]) dfs(i);
} int solve(int p){
if(dp[p]) return dp[p];
for(int i = first1[p];~i;i = e1[i].next){
int v = e1[i].v;
dp[p] = max(dp[p],solve(v));
}
return dp[p] = dp[p] + scn[p];
} int main(){
int T;
scanf("%d",&T);
while(T--){
init();
scanf("%d %d",&n,&m);
for(int i = ;i < m;i++ ){
int u,v;
scanf("%d %d",&u,&v);
addedges(u,v);
}
find_scc(); for(int u = ;u <= n;u++){
for(int i = first[u];~i;i = e[i].next){
int v = e[i].v;
if(sc[u] != sc[v]) addedges1(sc[u],sc[v]);
}
} int ans = ;
for(int i = ;i <= scnt;i++) ans = max(ans,solve(i));
printf("%d\n",ans);
}
return ;
}

还有另一种做法是,建立一个超级源点,与入度为0的scc节点连接,做一次spfa,求出路径上的最大点权和

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
using namespace std; const int maxn = ;
const int INF = ;
int n,m;
int first[maxn];
int sc[maxn],scn[maxn],low[maxn],pre[maxn];
int scnt,ecnt,dfs_clock;
int dp[maxn]; int du[maxn];
int dis[maxn];
int inq[maxn]; int first1[maxn];
int ecnt1; struct Edge{
int v,next;
}e[maxn*]; Edge e1[maxn*]; stack<int> S;
vector<int> g[maxn];
int val[maxn]; void init(){
ecnt = ecnt1 = ;
memset(first,-,sizeof(first));
memset(val,,sizeof(val));
memset(du,,sizeof(du));
} void addedges(int u,int v){
e[ecnt].v = v;
e[ecnt].next = first[u];
first[u] = ecnt++;
} void dfs(int u){
low[u] = pre[u] = ++dfs_clock;
S.push(u);
for(int i = first[u];~i;i = e[i].next){
int v = e[i].v;
if(!pre[v]){
dfs(v);
low[u] = min(low[u],low[v]);
}
else if(!sc[v]) low[u] = min(low[u],pre[v]);
}
if(pre[u] == low[u]){
scnt++;
for(;;){
int x = S.top();S.pop();
sc[x] = scnt;
val[scnt]++;
if(x == u) break;
}
}
} void find_scc(){
while(!S.empty()) S.pop();
scnt = dfs_clock = ;
memset(low,,sizeof(low));memset(pre,,sizeof(pre));
memset(sc,,sizeof(sc));memset(scn,,sizeof(scn)); for(int i = ;i <= n;i++) if(!pre[i]) dfs(i);
} int spfa(){
memset(inq, , sizeof(inq));
queue<int>q;
g[].clear();
q.push();
dis[] = ; val[] = ;
for(int i = ; i <= scnt; i++){if(du[i] == )g[].push_back(i); dis[i] = -INF;}
int ans = ;
while(!q.empty()){
int u = q.front(); q.pop(); inq[u] = ;
for(int i = ; i < g[u].size(); i++){
int v = g[u][i];
if(dis[v] < dis[u] + val[v]){
dis[v] = dis[u] + val[v];
ans = max(ans, dis[v]);
if(inq[v] == )inq[v] = , q.push(v);
}
}
}
return ans;
} int main(){
int T;
scanf("%d",&T);
while(T--){
init();
scanf("%d %d",&n,&m);
for(int i = ;i < m;i++ ){
int u,v;
scanf("%d %d",&u,&v);
addedges(u,v);
}
find_scc();
for(int i = ;i <= scnt;i++) g[i].clear(); for(int u = ;u <= n;u++){
for(int i = first[u];~i;i = e[i].next){
int v = e[i].v;
if(sc[u] != sc[v]) g[sc[u]].push_back(sc[v]),du[sc[v]]++;
}
}
printf("%d\n",spfa());
}
return ;
}

Uva 11324 The Largest Clique【强连通 DAG动规 spfa】的更多相关文章

  1. uva 11324 The Largest Clique(强连通分量缩点+DAG动态规划)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=sh ...

  2. UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)

    题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...

  3. UVa 11324 The Largest Clique (强连通分量+DP)

    题意:给定一个有向图,求一个最大的结点集,使得任意两个结点,要么 u 能到 v,要么 v 到u. 析:首先,如果是同一个连通分量,那么要么全选,要么全不选,然后我们就可以先把强连通分量先求出来,然后缩 ...

  4. UVA - 11324 The Largest Clique (强连通缩点+dp)

    题目链接 题意:从有向图G中找到一个最大的点集,使得该点集中任意两个结点u,v满足u可达v或v可达u. 解法:先把同处于一个强连通分量中的结点合并(缩点),得到一张DAG图,在DAG上dp即可. 感觉 ...

  5. UVA - 11324 The Largest Clique 强连通缩点+记忆化dp

    题目要求一个最大的弱联通图. 首先对于原图进行强连通缩点,得到新图,这个新图呈链状,类似树结构. 对新图进行记忆化dp,求一条权值最长的链,每一个点的权值就是当前强连通分量点的个数. /* Tarja ...

  6. UVA 11324 - The Largest Clique(强连通分量+缩点)

    UVA 11324 - The Largest Clique 题目链接 题意:给定一个有向图,要求找一个集合,使得集合内随意两点(u, v)要么u能到v,要么v能到u,问最大能选几个点 思路:强连通分 ...

  7. uva 11324 The Largest Clique

    vjudge 上题目链接:uva 11324 scc + dp,根据大白书上的思路:" 同一个强连通分量中的点要么都选,要么不选.把强连通分量收缩点后得到SCC图,让每个SCC结点的权等于它 ...

  8. uva 11324 The Largest Clique(图论-tarjan,动态规划)

    Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...

  9. UVA 11324 The Largest Clique (强连通分量,dp)

    给出一个有向图,求一个最大的结点集合,任意两个点u,v.u可到达v或v可到达u. 一个强连通分量肯定一起选的.而且只能在一条路径上. 所以先找出所有scc,然后缩点找一条最大权的路径,按拓扑序跑DAG ...

随机推荐

  1. -webkit-appearance: none; 去除浏览器默认样式

    -webkit-appearance: none;    去除浏览器默认样式

  2. codeforces 789 B. Masha and geometric

    链接 B. Masha and geometric depression 题意 给你一个等比数列的首项和公比q,然后给出一个上限l,m个数字,在这个等比数列里,小于l且没有在m个数字里面出现过的可以写 ...

  3. Java导出Excel文件的两种方法

    将数据以Excel表格的形式导出:首先下载poi的jar包,导入项目中,或者使用maven仓库管理,在pom文件添加:<dependency>    <groupId>org. ...

  4. Corn Fields 状压动归入门题

    #include<cstdio> using namespace std; const int N=15; int dp[N][1<<N],v[1<<N],M[N] ...

  5. 微信公众号开发之获取微信用户的openID

    (注:openID同一用户同一应用唯一,UnionID同一用户不同应用唯一.不同应用指微信开放平台下的不同用户.) 1.  申请测试号(获得appID.appsecret) 2.  填写服务器配置并验 ...

  6. maven 依赖的传递性

    1.如图我们有三个项目,项目Age,项目Bge,项目Cge 2.我们使Age项目依赖到Bge项目,Bge项目依赖到Cge项目 Age项目和Bge项目分别执行命令:mvn install  打包*.ja ...

  7. Linux 文件压缩

    压缩工具   compress/uncompress:对应 .Z 结尾的压缩格式文件  压缩格式:gz.bz2.xz.zip.Z gzip  压缩文件并删除源文件(生成.gz的文件) gunzip 解 ...

  8. Problem 11

    Problem 11 # Problem_11.py """ In the 20×20 grid below, four numbers along a diagonal ...

  9. PHP学习总结(7)——PHP入门篇之PHP注释

    注释 在PHP中也有注释语句:用双斜杠(//)来表示.其它语言中,Html中使用<!--注释语句-->,CSS中使用/*注释语句*/.如下面代码: <?php//输出hi,imooc ...

  10. CF47A Triangular numbers

    CF47A Triangular numbers 题意翻译 给定一个数n,问你是否存在一个整数i,满足i*(i+1)/2=n. 若存在,输出"YES",否则输出"NO&q ...