树的重心/深搜
图中点的层次/宽搜
有向图的拓扑排序
Dijkstra求最短路
bellman-ford
spfa求最短路
spfa判负环
floyd求最短路
prim求最小生成树
kruskal求最小生成树
判定二分图
匈牙利算法/二分图的最大匹配
树的重心/深搜
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n;
struct node{
int to,next;
}edge[N*2];
int head[2*N];
int cnt;
bool vis[N];
void add(int u,int v)
{
edge[++cnt] = {v,head[u]};
head[u] = cnt;
}
int ans= N;
int dfs(int u)
{
int res = 0,sum = 1;
vis[u] = 1;
for(int i = head[u];i;i=edge[i].next)
{
int to = edge[i].to;
if(vis[to] == 0)
{
int s = dfs(to);
res = max(res, s);
sum += s;
}
}
res = max(res , n - sum);
ans = min(ans, res);
return sum;
}
int main()
{
cin>>n;
for(int i = 1;i < n;i++)
{
int u,v;
cin>>u>>v;
add(u , v);
add(v , u);
}
dfs(1);
cout<<ans<<"\n";
return 0;
}
图中点的层次/宽搜
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
struct node{
int to,next;
}edge[N];
int head[N];
int cnt;
int n,m;
int dist[N];
bool vis[N];
void add(int u,int v)
{
edge[++cnt]={v,head[u]};
head[u] = cnt;
}
priority_queue<pair<int,int> > q;
int dfs()
{
memset(dist,0x3f,sizeof dist);
q.push({0,1});
dist[1] = 0;
while(!q.empty())
{
int now = q.top().second;
q.pop();
if(vis[now] == 1) continue;
vis[now] = 1;
if(now == n)
{
return dist[now];
}
for(int i = head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if(dist[to] > dist[now] + 1)
{
dist[to] = dist[now] + 1;
q.push({-1*dist[to],to});
}
}
}
return -1;
}
int main()
{
cin>>n>>m;
for(int i = 1;i <= m;i++)
{
int u,v;
cin>>u>>v;
add(u,v);
}
cout<<dfs();
return 0;
}
有向图的拓扑序列
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int m,n;
vector<int>e[N],tp;
int d[N];
queue<int>q;
int toposort()
{
for(int i = 1;i <= n;i++)
if(d[i] == 0) q.push(i);
while(!q.empty())
{
int now = q.front();
q.pop();
tp.push_back(now);
for(auto i : e[now])
{
if(--d[i] == 0) q.push(i);
}
}
return (tp.size() == n);
}
int main()
{
cin>>n>>m;
for(int i = 1;i <= m;i++)
{
int u,v;
cin>>u>>v;
d[v]++;
e[u].push_back(v);
}
bool f = toposort();
if(f == 0) cout<<-1<<"\n";
else
{
for(auto i : tp)
{
cout<<i<<" ";
}
}
return 0;
}
Dijkstra求最短路
#include <bits/stdc++.h>
using namespace std;
const int N = 150005;
int n,m;
struct node{
int to,w,next;
}edge[N];
int head[N];
int cnt;
void add(int u,int v,int w)
{
edge[++cnt] = {v,w,head[u]};
head[u] = cnt;
}
int dist[N];
bool vis[N];
priority_queue<pair<int ,int > > q;
void dijkstra()
{
memset(dist,0x3f,sizeof dist);
q.push({0,1});
dist[1] = 0;
while(!q.empty())
{
int now = q.top().second;
q.pop();
if(vis[now] == 1) continue;
vis[now] = 1;
for(int i = head[now];i;i=edge[i].next)
{
int to = edge[i].to;
int w = edge[i].w;
if(dist[to] > dist[now] + w)
{
dist[to] = dist[now] + w;
q.push({-1*dist[to],to});
}
}
}
if(dist[n] >= 0x3f3f3f3f) cout<<"-1"<<"\n";
else cout<<dist[n]<<"\n";
return;
}
int main()
{
cin>>n>>m;
for(int i = 1;i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
dijkstra();
return 0;
}
bellman-ford
#include <bits/stdc++.h>
using namespace std;
struct node{
int u,v,w;
}edge[10005];
int n,m,k;
int dist[505];
int dist2[505];
void bellman()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i = 0;i < k;i++)
{
memcpy(dist2,dist,sizeof dist);
for(int j = 1;j <= m;j++)
{
int u = edge[j].u;
int v = edge[j].v;
int w = edge[j].w;
dist[v] = min(dist2[u]+w,dist[v]);
}
}
if(dist[n] >= 0x3f3f3f3f/2) cout<<"impossible"<<"\n";
else cout<<dist[n]<<"\n";
}
int main()
{
cin>>n>>m>>k;
for(int i = 1;i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
edge[i] = {u,v,w};
}
bellman();
return 0;
}
spfa求最短路
#include <bits/stdc++.h>
using namespace std;
struct node{
int u,v,w;
}edge[10005];
int n,m,k;
int dist[505];
int dist2[505];
void bellman()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i = 0;i < k;i++)
{
memcpy(dist2,dist,sizeof dist);
for(int j = 1;j <= m;j++)
{
int u = edge[j].u;
int v = edge[j].v;
int w = edge[j].w;
dist[v] = min(dist2[u]+w,dist[v]);
}
}
if(dist[n] >= 0x3f3f3f3f/2) cout<<"impossible"<<"\n";
else cout<<dist[n]<<"\n";
}
int main()
{
cin>>n>>m>>k;
for(int i = 1;i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
edge[i] = {u,v,w};
}
bellman();
return 0;
}
spfa判负环
#include <bits/stdc++.h>
using namespace std;
const int N = 2005,M = 1e5+5;
int n,m;
struct node{
int to,next,w;
}edge[M];
int head[M];
int cnt = 0;
void add(int u,int v,int w)
{
edge[++cnt] = {v, head[u],w};
head[u] = cnt;
}
queue<int>q;
bool vis[N];
int dist[N];
int sum[N];
bool spfa()
{
for(int i = 1;i <= n;i++)
{
q.push(i);
vis[i] = 1;
}
while(!q.empty())
{
int now = q.front();
q.pop();
vis[now] = 0;
for(int i = head[now];i!=-1;i=edge[i].next)
{
int to = edge[i].to;
int w = edge[i].w;
if(dist[to] > dist[now] + w)
{
dist[to] = dist[now] + w;
sum[to] = sum[now] + 1;
if(sum[to] >= n) return 1;
if(vis[to] == 0)
{
q.push(to);
vis[to] = 1;
}
}
}
}
return 0;
}
int main()
{
memset(head,-1,sizeof head);
cin>>n>>m;
for(int i = 1;i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
bool f = spfa();
if(f == 0) cout<<"No"<<"\n";
else cout<<"Yes"<<"\n";
return 0;
}
floyd求最短路
#include <bits/stdc++.h>
using namespace std;
int n,m,k;
int d[205][205];
int main()
{
cin>>n>>m>>k;
memset(d,0x3f,sizeof d);
for(int i = 1;i <= n;i++) d[i][i] = 0;
for(int i = 1;i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
d[u][v] = min(d[u][v] ,w);
}
for(int l = 1;l <= n;l++)
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
d[i][j] = min(d[i][j],d[i][l]+d[l][j]);
for(int i = 1;i <= k;i++)
{
int u,v;
cin>>u>>v;
if(d[u][v] >= 0x3f3f3f) cout<<"impossible"<<"\n";
else cout<<d[u][v]<<"\n";
}
return 0;
}
prim求最小生成树
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int g[N][N], dt[N], st[N];
int n,m;
void prim()
{
memset(dt, 0x3f, sizeof dt);
int res = 0;
dt[1] = 0;
for(int i = 0; i < n;i++)
{
int t = -1;
for(int j = 1; j <= n;j++)
if(st[j] == 0 && (t == -1 || dt[j]< dt[t])) t = j;
if(dt[t] == 0x3f3f3f3f)
{
cout<<"impossible"<<"\n";
return;
}
st[t] = 1;
res += dt[t];
for(int i = 1; i <= n;i++)
if(dt[i] > g[t][i] && st[i] == 0)
dt[i] = g[t][i];
}
cout<<res<<"\n";
}
int main()
{
memset(g , 0x3f,sizeof g);
cin>>n>>m;
for(int i = 1; i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
g[u][v] = g[v][u] = min(g[u][v] , w);
}
prim();
return 0;
}
kruskal求最小生成树
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n,m;
struct node{
int u,v,w;
}e[N];
int f[N];
bool cmp(node a1,node a2)
{
return a1.w < a2.w;
}
int find(int x)
{
if(f[x] == x) return x;
return f[x] = find(f[x]);
}
void kruskal()
{
int ans = 0,sum = 1;
for(int i = 1;i <= m;i++)
{
int u = e[i].u;
int v = e[i].v;
int w = e[i].w;
int uu = find(u);
int vv = find(v);
if(uu != vv)
{
f[uu] = vv;
ans+=w;
sum++;
}
}
if(sum < n)
{
cout<<"impossible"<<"\n";
return;
}
cout<<ans<<"\n";
return;
}
int main()
{
cin>>n>>m;
for(int i = 1;i <= n;i++) f[i] = i;
for(int i = 1;i <= m;i++)
{
int u,v,w;
cin>>u>>v>>w;
e[i] = {u,v,w};
}
sort(e+1,e+m+1,cmp);
kruskal();
return 0;
}
判定二分图(染色法)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n,m;
struct node{
int to,next;
}edge[2*N];
int head[2*N];
int cnt;
int color[N];
void add(int u,int v)
{
edge[++cnt] = {v,head[u]};
head[u]=cnt;
}
bool dfs(int u,int col)
{
color[u] = col;
for(int i = head[u];i;i=edge[i].next)
{
int to = edge[i].to;
if(color[to] == 0)
{
if(dfs(to,3 - col) == 0) return 0;
}
else
{
if(color[to] + col != 3) return 0;
}
}
return 1;
}
int main()
{
cin>>n>>m;
for(int i = 1;i <= m;i++)
{
int u,v;
cin>>u>>v;
add(u , v);
add(v, u);
}
bool f = 0;
for(int i = 1;i <= n;i++)
{
if(color[i]==0)
{
if(dfs(i,1) == 0)
{
cout<<"No"<<"\n";
f = 1;
break;
}
}
}
if(f == 0) cout<<"Yes"<<"\n";
return 0;
}
匈牙利算法/二分图的最大匹配
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n1,n2,m;
struct node{
int to,next;
}edge[N];
int head[N];
int cnt;
bool vis[505];
int f[505];
void add(int u,int v)
{
edge[++cnt] = {v , head[u]};
head[u] = cnt;
}
bool find(int x)
{
for(int i = head[x];i;i=edge[i].next)
{
int to = edge[i].to;
if(vis[to] == 0)
{
vis[to] = 1;
if(f[to] == 0 || find(f[to]))
{
f[to] = x;
return 1;
}
}
}
return 0;
}
int main()
{
cin>>n1>>n2>>m;
for(int i = 1;i <= m;i++)
{
int u,v;
cin>>u>>v;
add(u , v);
}
int ans = 0;
for(int i = 1;i <= n1;i++)
{
memset(vis,0,sizeof vis);
if(find(i) == 1) ans++;
}
cout<<ans<<"\n";
return 0;
}

1472

被折叠的 条评论
为什么被折叠?



