堆优化的 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;
}