POJ2553

题意:很难懂!但是大体意思就是求有向图中从一个节点出发到达的点也能反向到达该节点的点。如a能到{b1,b2.....bx}这些点,而这些点也能到a,则a为要求的点。题目是求出所有的这种点。

对图进行缩点,缩点后出度为0的点(强连通分量)所包含的点就是答案。原因,自己思考一下.....

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stack>
  6 #include<vector>
  7 using namespace std;
  8 const int maxn=5010;
  9 const int maxm=500010;
 10 int n,m;
 11 struct edge
 12 {
 13     int u,v,next;
 14 }e[maxm],ee[maxm];
 15 int head[maxn],js,headd[maxn],jss;
 16 int dfsn[maxn],low[maxn],visx,sshu;
 17 int belong[maxn],ss[maxn];
 18 stack<int>st;
 19 bool ins[maxn];
 20 int chudu[maxn];
 21 vector<int>bl[maxn];
 22 vector<int>ans;
 23 void init()
 24 {
 25     memset(head,0,sizeof(head));
 26     memset(e,0,sizeof(e));
 27     js=0;
 28     memset(headd,0,sizeof(headd));
 29     memset(ee,0,sizeof(ee));
 30     jss=0;
 31     memset(dfsn,0,sizeof(dfsn));
 32     memset(low,0,sizeof(low));
 33     visx=sshu=0;
 34     memset(belong,0,sizeof(belong));
 35     memset(ss,0,sizeof(ss));
 36     while(!st.empty())st.pop();
 37     memset(ins,0,sizeof(ins));
 38     memset(chudu,0,sizeof(chudu));
 39     ans.resize(0);
 40     for(int i=0;i<maxn;i++)bl[i].resize(0);
 41 }
 42 void addage(int u,int v,edge e[],int head[],int &js)
 43 {
 44     e[++js].u=u;e[js].v=v;
 45     e[js].next=head[u];head[u]=js;
 46 }
 47 void tarjan(int u)
 48 {
 49     low[u]=dfsn[u]=++visx;
 50     st.push(u);
 51     ins[u]=1;
 52     for(int i=head[u];i;i=e[i].next)
 53     {
 54         int v=e[i].v;
 55         if(dfsn[v]==0)
 56         {
 57             tarjan(v);
 58             low[u]=min(low[u],low[v]);
 59         }
 60         else if(ins[v] && low[u]>dfsn[v]) low[u]=dfsn[v];
 61     }
 62     if(low[u]==dfsn[u])
 63     {
 64         sshu++;
 65         int tp;
 66         do{
 67             tp=st.top();
 68             st.pop();
 69             ins[tp]=0;
 70             bl[sshu].push_back(tp);
 71             belong[tp]=sshu;
 72             ss[sshu]++;
 73         }while(tp!=u);
 74     }
 75 }
 76 void addd(int x)
 77 {
 78     for(int i=0;i<bl[x].size();i++)
 79     {
 80         int y=bl[x][i];
 81         ans.push_back(y);
 82     }
 83 }
 84
 85 int main()
 86 {
 87     while(scanf("%d%d",&n,&m)==2)
 88     {
 89         init();
 90         for(int u,v,i=0;i<m;i++)
 91         {
 92             scanf("%d%d",&u,&v);
 93             addage(u,v,e,head,js);
 94         }
 95         for(int i=1;i<=n;i++)
 96             if(dfsn[i]==0)tarjan(i);
 97         for(int i=1;i<=m;i++)
 98         {
 99             int u=e[i].u,v=e[i].v;
100             if(belong[u]!=belong[v])
101             {
102                 addage(belong[u],belong[v],ee,headd,jss);
103                 chudu[belong[u]]++;
104             }
105         }
106         for(int i=1;i<=sshu;i++)
107             if(chudu[i]==0)addd(i);
108         sort(ans.begin(),ans.end());
109         for(int i=0;i<ans.size();i++)printf("%d ",ans[i]);
110         printf("\n");
111     }
112
113     return 0;
114 }

时间: 2024-10-30 23:23:25

POJ2553的相关文章

poj2553 强连通

题意:定义了一个图的底(bottom),是指在一个图中能够被所有点到达的点,问途中有哪些点是图的底. 首先是同一个强连通分量中的点都能够互相到达,强连通分量中一个点能到达其他点,也必然代表该强连通分量中的点能到达那个点,所以首先强连通,然后此时如果一个点是有出度的,那么它指向的点必然不能到它,所以其实就是求出度为 0 的强连通分量内的点. 1 #include<stdio.h> 2 #include<string.h> 3 #include<stack> 4 #incl

poj2553——The Bottom of a Graph(强连通分量)

Description We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called vertices (or nodes). Let E be a subset of the Cartesian product V×V, its elements being called edges. Then G

POJ2553 The Bottom of a Graph(强连通分量+缩点)

题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 5555 6 #define MAXM 5555*5555 7 struct Edge{ 8 int u,v,nex

poj2553 强连通缩点

The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10114   Accepted: 4184 Description We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called ve

【poj2553】The Bottom of a Graph(强连通分量缩点)

题目链接:http://poj.org/problem?id=2553 [题意] 给n个点m条边构成一幅图,求出所有的sink点并按顺序输出.sink点是指该点能到达的点反过来又能回到该点. [思路] 不难想象sink点一定是在强连通分量中,而且强连通分量缩点后出度为0,就可以说明该强连通分量内所有的点都是sink点. 之前wa了一发是因为写成了out[i],注意是从缩点构成的dag中找出度为0的点,而不是从原来的图中找. [ac代码] #include <cstdio> #include &

最长上升子序列LIS解法(n^n &amp;&amp; nlogn)

最长递增子序列问题 在一列数中寻找一些数满足 任意两个数a[i]和a[j] 若i<j 必有a[i]<a[j] 这样最长的子序列称为最长递增子序列LIS LIS问题有两种常见的解法 一种时间复杂度n^n 一种时间复杂度nlogn 下面我们先来说一下n^n的算法 设dp[i]表示以i结尾的最长上升子序列的长度 把问题分解 分解成序列中每一项最为终点的最大上升子序列 从第二项开始依次判断 最后找出最大的一项就是答案 则状态转移方程为 dp[i] = max{dp[j]+1}, 1<=j<

poj图论解题报告索引

最短路径: poj1125 - Stockbroker Grapevine(多源最短路径,floyd) poj1502 - MPI Maelstrom(单源最短路径,dijkstra,bellman-ford,spfa) poj1511 - Invitation Cards(单源来回最短路径,spfa邻接表) poj1797 - Heavy Transportation(最大边,最短路变形,dijkstra,spfa,bellman-ford) poj2240 - Arbitrage(汇率问题,

图论专题整理

poj1251 Jungle Roads 思路:最小生成树          解题报告Here CodeForces 472D Design Tutorial: Inverse the Problem 思路:最小生成树          解题报告Here poj1789 Truck History 思路:最小生成树          解题报告Here poj1639 Picnic Planning 思路:顶点度数限制的MST         解题报告Here poj1062 昂贵的聘礼 思路:S

POJ2533&amp;&amp;SP1799 The Bottom of a Graph(tarjan+缩点+强连通分量)

POJ2553 SP1799 我们知道单独一个强连通分量中的所有点是满足题目要求的 但如果它连出去到了其他点那里,要么成为新的强连通分量,要么失去原有的符合题目要求的性质 所以只需tarjan缩点求出所有强连通分量,再O(E)枚举所有边,是否会成为连接一个分量与另一个分量的边--即一条出度--即可 如果一个分量没有出度,那么他中间的所有点都是符合题目要求的点 (因为快读快输加了太长所以就不贴了) const int N=5005,M=N*N>>1; int h[N],en,n,m,dfn[N]