最大编号 tarjan+逆向建图拓扑排序+DAG上DP
标签:ios put 拓扑排序 sign des c++ cst ack end
给出N 个点,M 条边的有向图,对于每个点v,求A(v) 表示从点v 出发,能到达的编号最大的点。
Input
第1 行,2 个整数N;M。
接下来M 行,每行2 个整数Ui,Vi,表示边(Ui,Vi)。点用1,2,...,N 编号。
Output
输出仅一行为N 个整数A(1),A(2),...,A(N)。
Sample Input
4 3
1 2
2 4
4 3
Hint
对于60% 的数据,1对于100% 的数据,1
这题实际上很水了
有向图就提示你环肯定先取环里面的最大值
缩环之后逆拓扑排序求出一个DAG序列
在DAG上任意做DP求最大值就好啦!
code:
1 #include 2 #include 3 #include 4 #define N 100005
5 using namespace std;
6 struct node{
7 int u,v;
8 }e[N],e1[N];
9 int first[N],nxt[N],cnt,n,m;
10 void add(int u,int v){
11 e[++cnt].u=u;
12 e[cnt].v=v;
13 nxt[cnt]=first[u];
14 first[u]=cnt;
15 }
16 int first1[N],nxt1[N],cnt1;
17 void add1(int u,int v){
18 e1[++cnt1].u=u;
19 e1[cnt1].v=v;
20 nxt1[cnt1]=first1[u];
21 first1[u]=cnt1;
22 }
23 int low[N],dfn[N],instack[N],stack[N],belong[N],maxpo[N],sign,bcc,top1;
24 void tarjan(int x){
25 low[x]=dfn[x]=++sign;
26 stack[++top1]=x;
27 instack[x]=1;
28 for(int i=first[x];i;i=nxt[i]){
29 int v=e[i].v;
30 if(!dfn[v]){
31 tarjan(v);
32 low[x]=min(low[x],low[v]);
33 }
34 else if(instack[v])low[x]=min(low[x],dfn[v]);
35 }
36 if(dfn[x]==low[x]){
37 bcc++;
38 int t;
39 do{
40 t=stack[top1--];
41 belong[t]=bcc;
42 instack[t]=0;
43 maxpo[bcc]=max(maxpo[bcc],t);
44 // cout
45 }while(x!=t);
46 }
47 }
48 priority_queueint>q;
49 int ru[N],top[N],tot;
50 void topsort(){
51 for(int i=1;i){
52 if(!ru[i]){
53 q.push(i);
54 }
55 }
56 while(!q.empty()){
57 int u=q.top();
58 q.pop();
59 top[++tot]=u;
60 for(int i=first1[u];i;i=nxt1[i]){
61 int v=e1[i].v;
62 ru[v]--;
63 if(!ru[v]){
64 q.push(v);
65 }
66 }
67 }
68 }
69 int a[N],b[N];
70 int main(){
71 cin>>n>>m;
72 for(int i=1;i){
73 cin>>a[i]>>b[i];
74 add(a[i],b[i]);
75 }
76 for(int i=1;i){
77 if(!dfn[i])tarjan(i);
78 }
79 for(int i=1;i){
80 if(belong[a[i]]==belong[b[i]])continue;
81 add1(belong[b[i]],belong[a[i]]);//反向建图才能够确定拓扑序的dp顺序
82 ru[belong[a[i]]]++;
83 // cout
84 }
85 topsort();
86 // for(int i=1;i
87 for(int i=1;i){
88 int u=top[i];
89 for(int j=first1[u];j;j=nxt1[j]){
90 int v=e1[j].v;
91 maxpo[v]=max(maxpo[v],maxpo[u]);
92 }
93 }
94 for(int i=1;i){
95 cout" ";
96 }
97 return 0;
98 }
over
最大编号 tarjan+逆向建图拓扑排序+DAG上DP
标签:ios put 拓扑排序 sign des c++ cst ack end
原文地址:https://www.cnblogs.com/saionjisekai/p/9726854.html
评论