【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm

缩点后转化成 DAG图上的单源最长路问题。spfa/dp随便。

 1 #include<cstdio>
 2 #include<queue>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstring>
 6 using namespace std;
 7 int cmp[500001],sum,n,m,Us[500001],Vs[500001],t,w[500001],sta,k,ans,dis[500001];
 8 bool vis[500001],inq[500001];
 9 struct Edge{int v,w;Edge(const int &a,const int &b){v=a;w=b;}Edge(){}};
10 vector<int>G[500001],rG[500001],G2[500001],vs;
11 typedef vector<int>::iterator ITER;
12 queue<int>q;
13 void dfs(int U)
14 {
15     vis[U]=1;
16     for(ITER it=G[U].begin();it!=G[U].end();++it) if(!vis[*it]) dfs(*it);
17     vs.push_back(U);
18 }
19 void dfs2(int U)
20 {
21     cmp[U]=sum;
22     for(ITER it=rG[U].begin();it!=rG[U].end();++it) if(!cmp[*it]) dfs2(*it);
23 }
24 void scc()
25 {
26     for(int i=1;i<=n;i++) if(!vis[i]) dfs(i);
27     ITER it=vs.end(); --it;
28     for(;;it--)
29       {
30         if(!cmp[*it]) {++sum; dfs2(*it);}
31         if(it==vs.begin()) break;
32       }
33 }
34 void spfa(const int &s)
35 {
36     dis[s]=w[s]; q.push(s); inq[s]=1;
37     while(!q.empty())
38       {
39         int U=q.front();
40         for(ITER it=G2[U].begin();it!=G2[U].end();it++)
41           if(dis[*it]<dis[U]+w[*it])
42             {
43               dis[*it]=dis[U]+w[*it];
44               if(!inq[*it])
45                 {
46                   q.push(*it);
47                   inq[*it]=1;
48                 }
49             }
50         q.pop(); inq[U]=0;
51       }
52 }
53 int main()
54 {
55     scanf("%d%d",&n,&m);
56     for(int i=1;i<=m;++i)
57       {
58           scanf("%d%d",&Us[i],&Vs[i]);
59           G[Us[i]].push_back(Vs[i]);
60           rG[Vs[i]].push_back(Us[i]);
61       } scc();
62     for(int i=1;i<=n;++i) {scanf("%d",&t); w[cmp[i]]+=t;}
63     for(int i=1;i<=m;++i)
64       if(cmp[Us[i]]!=cmp[Vs[i]])
65         G2[cmp[Us[i]]].push_back(cmp[Vs[i]]);
66     scanf("%d%d",&sta,&k);
67     spfa(cmp[sta]);
68     for(int i=1;i<=k;++i)
69       {
70           scanf("%d",&t);
71           ans=max(dis[cmp[t]],ans);
72       } printf("%d\n",ans);
73     return 0;
74 }
时间: 2024-10-06 01:14:41

【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm的相关文章

【强联通分量缩点】【最长路】【spfa】CH Round #59 - OrzCC杯NOIP模拟赛day1 队爷的讲学计划

10分算法:对于城市网络为一条单向链的数据, 20分算法:对于n<=20的数据,暴力搜出所有的可能路径. 结合以上可以得到30分. 60分算法:分析题意可得使者会带着去的城市也就是这个城市所在强联通分量的其他城市,这个过程的代价也就是这个强联通分量的城市数-1,且他可以选择任何一个其中的城市离开这个强联通分量.于是我们求出所有强联通分量,记录下每一个包含的城市数,然后缩点.接下来再用dfs,由于数据是构造的,只能得到60分. 100分算法:在缩点之后,这个图变成了一个有向无环图,我们将一条边连向

【POJ1236】Network of Schools 强联通分量缩点(本文kosaraju)

/*不要说这题多水之类的--我只是想记一下kosaraju这种屌炸天的dfs序延伸算法(说不定能加到我的ygylca里面)*/ 题意神马的都不说了,好吧,就是给你个图,n个点,然后n行每行都描述该点的出边,图建完了,然后缩点,然后问多少个点没有入度,再问需要加几条边可以让图变强联通图. 强联通图:图中任意两点之间都能互相到达(前提得是有向图你懂的,无向图就有点乱了,根本不要算法了,暴搜就好了) 强联通分量:同强联通图,不过是图中一部分. 缩点,把一个分量视为一个点,缩起来(一般不缩,都是记录每个

hihoCoder#1185 : 连通性&#183;三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

题目链接: http://hihocoder.com/problemset/problem/1185# 题意: n个点,每个点有一个权值,m条有向边,从1出发,每走到一个点, 就吃掉这个点的草,当没有可以到达的草场或是能够到达的草场都已经被吃光了之后就要返回到1了.求最多可以吃掉多少草. 思路: 提示里面讲的挺好的 如果草场是一个强连通图,那么我们只要走到任意一点,就可以把其他所有的草场都走一遍,并且可以选择任意一个点作为终点.所以把强联通块缩成一个点 因为一个强连通块会被缩成一个点,那么我们可

ZOJ 3795 Grouping(强联通分量 + 缩点 + Dp)

Problem Description: Suppose there are N people in ZJU, whose ages are unknown. We have some messages about them. The i-th message shows that the age of person si is not smaller than the age of person ti. Now we need to divide all these N people into

【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割

结论: 满足条件一:当一条边的起点和终点不在 残量网络的 一个强联通分量中.且满流. 满足条件二:当一条边的起点和终点分别在 S 和 T 的强联通分量中.且满流.. 网上题解很多的. 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define IN

【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数

两次dfs缩点,然后n次dfs暴搜. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 #define N 2001 6 vector<int>G[N],rG[N],vs,G2[N]; 7 typedef vector<int>::iterator ITER; 8 char s[N+1][N+1]; 9 int cmp[N],sum

Light OJ 1034 - Hit the Light Switches(强联通分量)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1034 题目大意:有n盏灯,有m个关系, 关系a,b表示如果a灯开关打开那么b灯也会亮起来, 现在求至少需要打开多少开关使所有灯都亮. 题目思路:先由强联通分量缩点, 得到DAG图, 然后根据DAG图,求出有多少入度为0的点, 即为所求. 代码如下: #include<bits/stdc++.h> using namespace std; const int N = 1000

codevs 2822 爱在心中 tarjan(强联通分量)

2822 爱在心中 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home.” 在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况).爱是具有传递性的,即如果A爱B,B爱C,则A也爱C.如果有这样一部分人,他们彼此都相爱,则他们就超越了一

[BZOJ1051] [HAOI2006] 受欢迎的牛 (强联通分量)

Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头 牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可 能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的. Sample Input 3