周末训练9.5

拓补排序:https://blog.csdn.net/qq_41713256/article/details/80805338

链式前向星:https://blog.csdn.net/sugarbliss/article/details/86495945

邻接表单向链表->传送门

邻接表:(vector)


1
2
3
4
5
6
7
8
vector<int> G[N];

int u,v;
scanf("%d%d",&u,&v);
G[u].push_back();

for(int i=0;i<G[p].size();i++)
{ int y=G[p][i]; }

快速幂:(模板)


1
2
3
4
5
6
7
8
9
10
11
ll ksm(ll a,ll b)
{
    ll x=1,s=a;
    while(b)
    {
        if(b%2==1) x=(x*s)%m;
        s=(s*s)%m;
        b/=2;
    }
    return x;
}

拓补排序:(有向无环图)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//↓T:旅行计划
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,INF=1e9;
int n,m;
vector<int> G[N];//邻接表
int rd[N];
queue<int> q;
int ans[N];
int main()
{
//  freopen("plan.in","r",stdin);
//  freopen("plan.out","w",stdout);
   
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);//邻接表
        rd[v]++;//记录入度
    }
    for(int i=1;i<=n;i++) if(rd[i]==0) q.push(i),ans[i]=1;//入度为0的入队
    while(!q.empty())
    {
        int p=q.front();q.pop();
        for(int i=0;i<G[p].size();i++)
        {
            int y=G[p][i];//找下一个点
            ans[y]=max(ans[y],ans[p]+1);//DP
            rd[y]--;//入度减一
            if(rd[y]==0) q.push(y);//如果入度为0就入队
        }
    }
    for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
   
    return 0;
}

 

比赛:

1.排序问题

题解:过两遍sort,注意mod后的赋值

2.阶乘取模

题解:快速幂

3.旅行计划

题解:拓补排序,注意每个点的初值为为1

4.城市重建

题解:邻接表Dijkstra(只能80分)