⑦2018=10.7

1/50


部分超链接中有题目,大部分有附代码,需要题目自行搜索引擎。

一些题目是书本中的例题,网络上可能找不到题目。

目前已涉及的算法/数据结构/内容有:Tarjan缩点,DP,拓扑排序

1.P3387 【模板】缩点(Tarjan缩点、DP、拓扑排序)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define min(a,b) ((a)<(b)?(a):(b))
 5 #define max(a,b) ((a)>(b)?(a):(b))
 6 using namespace std;
 7 const int maxn=10000,maxm=1e5;
 8 int N,M,dis[maxn+50],u,v,edge_head[maxn+50],num_edge=0;
 9 int St[maxn+50],top=0,DFN[maxn+50],LOW[maxn+50];
10 int ix=0,col=0,D[maxn+50],C[maxn+50],dp[maxn+50],ans=0,goin[maxn+50];
11 bool vis[maxn+50],book[maxn+50];
12 struct Edge{
13     int to,nx,from;
14 }edge[maxm+50];
15 inline void Add_edge(int from,int to){
16     edge[++num_edge].nx=edge_head[from];
17     edge[num_edge].from=from;
18     edge[num_edge].to=to;
19     edge_head[from]=num_edge;
20     return;
21 }
22 inline void Tarjan(int x){
23     DFN[x]=LOW[x]=++ix;
24     St[++top]=x;
25     vis[x]=1;
26     for(int i=edge_head[x];i;i=edge[i].nx){
27         int y=edge[i].to;
28         if(DFN[y]==0){
29             Tarjan(y);
30             LOW[x]=min(LOW[x],LOW[y]);
31         }
32         else if(vis[y])LOW[x]=min(LOW[x],DFN[y]);
33     }
34     if(DFN[x]==LOW[x]){
35         col++;
36         while(St[top]!=x){
37             D[col]+=dis[St[top]];
38             C[St[top]]=col;
39             vis[St[top]]=0;
40             top--;
41         }
42         D[col]+=dis[St[top]];
43         C[St[top]]=col;
44         vis[St[top]]=0;
45         top--;
46     }
47     return;
48 }
49 inline void Work(int x){
50     book[x]=1;
51     for(int i=1;i<=N;i++){
52         if(C[i]!=x)continue;
53         for(int j=edge_head[i];j;j=edge[j].nx){
54             int y=edge[j].to;
55             if(C[y]!=x){
56                 dp[C[y]]=max(dp[C[y]],dp[x]+D[C[y]]);
57                 ans=max(ans,dp[C[y]]);
58                 goin[C[y]]--;
59                 if(goin[C[y]]==0)Work(C[y]);
60             }
61         }
62     }
63     return;
64 }
65 int main(){
66     scanf("%d%d",&N,&M);
67     for(int i=1;i<=N;i++)scanf("%d",&dis[i]);
68     for(int i=1;i<=M;i++){
69         scanf("%d%d",&u,&v);
70         Add_edge(u,v);
71     }
72     for(int i=1;i<=N;i++)
73         if(DFN[i]==0)Tarjan(i);
74     for(int i=1;i<=col;i++){
75         dp[i]=D[i];
76         ans=max(ans,dp[i]);
77     }
78     for(int i=1;i<=num_edge;i++){
79         int a=edge[i].from,b=edge[i].to;
80         if(C[a]!=C[b])goin[C[b]]++;
81     }
82     for(int i=1;i<=col;i++)
83         if(goin[i]==0&&book[i]==0)Work(i);
84     printf("%d",ans);
85     return 0;
86 }
P3387 【模板】缩点

2.

猜你喜欢

转载自www.cnblogs.com/AlenaNuna/p/9750041.html