- ```
- #include<bits/stdc++.h>//请使用支持c++11的环境
- #pragma GCC optimize(2)
- using namespace std;
- typedef pair<int,int>PII;
- #define endl "\n"
- typedef unsigned long long ull;
- typedef long long ll;
- const int M=1010;
- const int INF=0x3f3f3f3f;
- const int mod=1e9+7;
- const int N=2e5+10;
- int dx[4]={0,1,0,-1};
- int dy[4]={-1,0,1,0};
- int w[M][M],s[M][M],dist[M],back[M],p[M],cnt[M];
- int n;//点数
- int len;//边数
- struct P{
- int ne,w;
- };
- struct Q{
- int a,b,w;
- }b[M*M];
- bool cmp(Q q,Q w){
- return q.w<w.w;
- }
- vector<P> a[M];
- bool st[M];
- int find(int x){//并查集
- if(p[x]==x) return x;
- return p[x]=find(p[x]);
- }
- void merge(int q,int w){//并查集合并优化
- q=find(q);w=find(w);
- if(cnt[q]==cnt[w]){
- p[w]=q;
- cnt[q]++;
- }
- else if(cnt[q]<cnt[w]){
- p[q]=w;
- }
- else{
- p[w]=q;
- }
- }
- void dfs_1(int x){//用邻接表
- st[x]=1;
- cout<<x<<" ";
- for(int i=0;i<a[x].size();i++){
- if(!st[a[x][i].ne])
- dfs_1(a[x][i].ne);
- }
- }
- void dfs_2(int x){
- st[x]=1;
- cout<<x<<" ";
- for(int i=1;i<=n;i++){
- if(!st[i]&&w[x][i]!=0x3f3f3f3f){
- dfs_2(i);
- }
- }
- }
- void bfs_1(){
- memset(st,0,sizeof st);
- queue<int> q;
- q.push(1);//默认从1开始
- st[1]=1;
- while(q.size()){
- int e=q.front();q.pop();
- cout<<e<<" ";
- for(int i=0;i<a[e].size();i++){
- if(!st[a[e][i].ne]){
- st[a[e][i].ne]=1;
- q.push(a[e][i].ne);
- }
- }
- }
- }
- void bfs_2(){
- memset(st,0,sizeof st);
- queue<int> q;
- q.push(1);//默认从1开始
- st[1]=1;
- while(q.size()){
- int e=q.front();q.pop();
- cout<<e<<" ";
- for(int i=1;i<=n;i++){
- if(!st[i]&&w[e][i]!=0x3f3f3f3f){
- st[i]=1;
- q.push(i);
- }
- }
- }
- }
- void dijkstra(int start,int end){//复杂度O(n*n+m)
- memset(dist,0x3f,sizeof dist);
- memset(st,0,sizeof st);
- dist[start]=0;
- int z=start;
- while(!st[end]&&z!=-1){
- st[z]=1;
- for(int i=0;i<a[z].size();i++){
- dist[a[z][i].ne]=min(dist[a[z][i].ne],dist[z]+a[z][i].w);
- }
- z=-1;
- for(int i=1;i<=n;i++){
- if(!st[i]&&dist[i]!=0x3f3f3f3f){
- if(z==-1||dist[z]>dist[i]) z=i;
- }
- }
- }
- if(!st[end]) cout<<"不可达"<<endl;
- else cout<<dist[end]<<endl;
- }
- void dijkstra_heap(int start,int end){//复杂度O(nlog n+m)
- memset(dist,0x3f,sizeof dist);
- memset(st,0,sizeof st);
- priority_queue<PII,vector<PII>,greater<PII>> heap;
- heap.push({0,start});
- dist[start]=0;
- while(!st[end]&&heap.size()){
- int p=heap.top().second;heap.pop();
- if(st[p]) continue;
- st[p]=1;
- cout<<p<<" ";
- for(int i=0;i<a[p].size();i++){
- if(st[a[p][i].ne]) continue;
- if(dist[a[p][i].ne]>dist[p]+a[p][i].w){
- dist[a[p][i].ne]=dist[p]+a[p][i].w;
- heap.push({dist[a[p][i].ne],a[p][i].ne});
- }
- }
- }
- if(dist[end]==0x3f3f3f3f) cout<<"不可达"<<endl;
- else cout<<dist[end]<<endl;
- }
- void floyd(){
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++){
- for(int k=1;k<=n;k++) w[j][k]=min(w[j][k],w[j][i]+w[i][k]);
- }
- }
- int q;
- cin>>q;//询问次数
- while(q--){
- int r,e;
- cin>>r>>e;
- cout<<w[r][e]<<endl;//输出r到e的最短路
- }
- }
- void bellman_ford(int start,int end){
- int k=n;
- memset(dist,0x3f,sizeof dist);
- dist[start]=0;
- while(k--){
- memcpy(back,dist,sizeof back);
- for(int i=2;i<=(len<<1|1);i++){
- dist[b[i].b]=min(back[b[i].a]+b[i].w,dist[b[i].b]);
- }
- }
- if(dist[end]>=0x3f3f3f3f/2) cout<<"不可达"<<endl;
- else cout<<dist[end]<<endl;
- }
- void spfa(int start,int end){//O(n*m)
- memset(dist,0x3f,sizeof dist);
- memset(st,0,sizeof st);
- queue<int> q;
- q.push(start);
- dist[start]=0;
- while(q.size()){
- int p=q.front();q.pop();
- st[p]=0;
- for(int i=0;i<a[p].size();i++){
- if(dist[a[p][i].ne]>dist[p]+a[p][i].w){
- dist[a[p][i].ne]=dist[p]+a[p][i].w;
- if(!st[a[p][i].ne]) q.push(a[p][i].ne);
- st[a[p][i].ne]=1;
- }
- }
- }
- if(dist[end]>=0x3f3f3f3f/2) cout<<"不可达"<<endl;
- else cout<<dist[end]<<endl;
- }
- void prim(){
- ll ans=0;
- memset(dist, 0x3f, sizeof dist);
- memset(st,0,sizeof st);
- for(int i=0;i<n;i++)
- {
- int t=-1;
- for(int j=1;j<=n;j++)
- {
- if(!st[j]&&(t==-1||dist[t]>dist[j])) t=j;
- }
- if (i&&dist[t]==0x3f3f3f3f){
- cout<<"不是连通图"<<endl;
- return;
- }
- if(i) ans+=dist[t];
- for(int j=2;j<=(len<<1|1);j++)
- {
- if(dist[j]>w[t][j]&&!st[j])
- dist[j]=min(dist[j],s[t][j]);
- }
- st[t]=1;
- }
- cout<<ans<<endl;
- }
- void kruskal(){//复杂度O(mlog m)
- for(int i=1;i<=n;i++) p[i]=i;
- sort(b+1,b+len+1,cmp);
- int cnt=0;ll ans=0;
- for(int i=2;i<=(len<<1|1);i++){
- int q=find(b[i].a),w=find(b[i].b);
- if(q!=w){
- cnt++;
- ans+=b[i].w;
- merge(q,w);
- }
- }
- if(cnt==n-1) cout<<ans<<endl;
- else cout<<"不可达"<<endl;
- }
- void solve()
- {
- cin>>n>>len;//点数上限为1009,边数上限为1010*1010-2
- memset(w,0x3f,sizeof w);//认为距离上限不超过 0x3f3f3f3f
- memset(s,0x3f,sizeof s);
- for(int i=1;i<=len;i++){//读入无向边 base_1
- int q,r,e;//e为边的长度
- cin>>q>>r>>e;
- if(q==r) continue;
- s[q][r]=w[q][r]=min(w[q][r],e);a[q].push_back({r,e});b[i<<1]={q,r,e};
- s[r][q]=w[r][q]=min(w[r][q],q);a[r].push_back({q,e});b[i<<1|1]={r,q,e};//若想为有向边,请给这一行前面加//
- }
- //默认从1开始
- dfs_1(1);
- cout<<endl;
- memset(st,0,sizeof st);
- dfs_2(1);
- cout<<endl;
- bfs_1();
- cout<<endl;
- bfs_2();
- cout<<endl;
- int start,end;
- cin>>start>>end;
- dijkstra(start,end);
- cin>>start>>end;
- dijkstra_heap(start,end);
- floyd();//请输入询问次数 再输入起始位置和终止位置
- cin>>start>>end;
- bellman_ford(start,end);
- cin>>start>>end;
- spfa(start,end);
- prim();
- kruskal();
- }
- int main()
- {
- //下列三行是开启同步,加快输入输出的,输出将会在所有输入完成后,若想按程序运行顺序输出请删除下列三行
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- solve();
- return 0;
- }
- ```
图论的一些算法(c++)
于 2022-05-25 23:04:41 首次发布