GESP模板

堆优化的 dijkstra

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define M N<<2

int head[N],Next[M],ver[M],edge[M];
int tot;
int dist[M];
bool vis[M];
priority_queue<pair<int,int>>Q;

void ADD(int x,int y,int z) {
	ver[++tot] = y;
	edge[tot] = z;
	Next[tot] = head[x];
	head[x] = tot;
}

void dijkstra(int s){
	memset(dist,0x3f,sizeof(dist));
	memset(vis,0,sizeof(vis));
	dist[s] = 0;
	Q.push(make_pair(0,s));
	while(!Q.empty()){
		int x = Q.top().second;
		Q.pop();
		if(vis[x]) continue;
		vis[x] = 1;
		for(int i = head[x];~i;i = Next[i]){
			int y = ver[i];
			if(dist[y]>dist[x]+edge[i]){
				dist[y] = dist[x]+edge[i];
				Q.push(make_pair(-dist[y],y));
			}
		}
	}
}

int main() {
	int n,m,s;
	memset(head,-1,sizeof(head));
	tot = -1;
	cin>>n>>m>>s;
	for(int i = 1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		ADD(x,y,z);
	}
	dijkstra(s);
	for(int i = 1;i<=n;i++){
		cout<<dist[i]<<" ";
	}
	return 0;
}

求组合数

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1000005;
const ll M = 1000000007;
ll f[N], g[N];
ll KSM(ll a, ll n)
{
    ll sum = 1;
    while (n)
    {
        if (n & 1)
            sum = sum * a % M;
        a = a * a % M;
        n >>= 1;
    }
    return sum;
}
void init(int n)
{
    f[0] = 1;
    for (int i = 1; i <= n; i++)
        f[i] = f[i - 1] * i % M;
    g[n] = KSM(f[n], M - 2);
    for (int i = n; i; i--)
        g[i - 1] = g[i] * i % M;
}
ll C(int n, int k)
{
    if (k < 0 || k > n)
        return 0;
    return f[n] * g[k] % M * g[n - k] % M;
}
int main()
{
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    init(1000003);
    int n, k;
    while (cin >> n >> k)
        cout << C(n, k) << endl;
    return 0;
}

最小生成树

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define M N<<1
#define INF 0x3f3f3f3f
int F[N],n,m,sum,num;
struct E{
	int x,y,z;
}edge[M];

void init(int n){
	for(int i = 1;i<=n;i++){
		F[i] = i;
	}
}

bool cmp(E a, E b){
	return a.z<b.z;
}

int Find(int x){
	if(x == F[x]) return x;
	return F[x] = Find(F[x]);
}

int kruskal(){
	sort(edge+1,edge+m+1,cmp);
	init(n);
	for(int i = 1;i<=m;i++){
		int x = Find(edge[i].x);
		int y = Find(edge[i].y);
		if(x == y) continue;
		F[x] = y;
		num++;
		sum+=edge[i].z;
	}
	if(num == n-1) return sum;
	else return INF;
}

int main(){
	cin>>n>>m;
	for(int i = 1;i<=m;i++){
		cin>>edge[i].x>>edge[i].y>>edge[i].z;
	}
	int ans = kruskal();
	if(ans == INF){
		puts("orz");
	}
	else{
		cout<<ans;
	}
	return 0;
}

LCA

#include <bits/stdc++.h>
using namespace std;
#define N 500005
int n, m;
int R;
int dn;
int dfn[N], mi[19][N];
vector<int> edge[N];
int get(int x, int y)
{
    return dfn[x] < dfn[y] ? x : y;
}

void dfs(int id, int f)
{
    mi[0][dfn[id] = ++dn] = f;
    for (int it : edge[id])
        if (it != f)
            dfs(it, id);
}

int LCA(int u, int v)
{
    if (u == v)
        return u;
    if ((u = dfn[u]) > (v = dfn[v]))
        swap(u, v);
    int d = __lg(v - u++);
    return get(mi[d][u], mi[d][v - (1 << d) + 1]);
}

int main()
{
    cin >> n >> m >> R;
    for (int i = 2, u, v; i <= n; i++)
    {
        cin >> u >> v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs(R, 0);
    for (int i = 1; i <= __lg(n); i++)
        for (int j = 1; j + (1 << i) - 1 <= n; j++)
            mi[i][j] = get(mi[i - 1][j], mi[i - 1][j + (1 << i - 1)]);
    for (int i = 1, u, v; i <= m; i++)
    {
        cin >> u >> v;
        cout << LCA(u, v) << "\n";
    }
    return 0;
}
posted @ 2024-12-07 00:59  薛儒浩  阅读(49)  评论(0)    收藏  举报