拓扑排序
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[101][101],c[101],r[101],ans[101]; int E; int head[100010]; int to[100010]; int nxt[100010]; void add_edge(int a, int b) { to[E] = b; nxt[E] = head[a]; head[a] = E; E ++; } void init() { E = 0; memset(head, -1, sizeof head); } int i,j,tot,temp,num,n,m; int main() { init(); cin >> n; for (i = 1; i <= n; i++) { do { cin >> j; if (j !=0 ) { c[i]++; add_edge(i, j); r[j]++; } } while (j != 0); } for (i=1;i<=n;i++) if (r[i] == 0) ans[++tot] = i; do { temp = ans[tot]; cout << temp << " "; tot--; num++; for (i = head[temp]; i != -1; i=nxt[i]) { r[to[i]]--; if (r[to[i]] == 0) ans[++tot] = to[i]; } } while (num != n); return 0; }
最短路
Dijkstra-邻接表
#include<iostream> #include<cstring> using namespace std; const int maxn=101; int f[maxn],d[maxn],path[maxn]; int n,m,start; int head[1001],num_edge; struct Edge { int next; int to; int w; } edge[1001]; const int inf=99999; void add_edge(int from,int to,int w) { edge[++num_edge].next=head[from]; edge[num_edge].to=to; edge[num_edge].w=w; head[from]=num_edge; } void init() { cin>>n>>m>>start; int x,y,w; for(int i=1; i<=m; i++) { cin>>x>>y>>w; add_edge(x,y,w); add_edge(y,x,w); } } void dijkstra(int s) { for (int i=1; i<=n; i++) { d[i]=inf; f[i]=false; } d[s]=0; for (int i=1; i<=n; i++) { int mind=inf; int k;//用来记录准备放入集合1的点 for (int j=1; j<=n; j++) //查找集合2中d[]最小的点 if ( (!f[j]) &&(d[j]<mind) ) { mind=d[j]; k=j; }; if (mind==inf) break; //更新结点求完了 f[k]=true; // 加入集合1 int j=head[k];//修改集合2中的d[j] while(j!=0) { int t=edge[j].to; if(!f[t] && d[k]+edge[j].w<d[t]) { d[t]=d[k]+edge[j].w; path[t]=k; } j=edge[j].next; } } } void dfs(int i) { if(i!=start) dfs(path[i]); cout<<i<<' '; } void write() { for (int i=1; i<=n; i++) if(i!=start) { dfs(i); cout<<d[i]<<endl; } } int main() { init(); dijkstra(start); write(); return 0; }
spfa 邻接表
#include <iostream> #include<cstdio> using namespace std; #define INF 0x3f3f3f3f const int maxn=1001,maxm=100001; struct Edge { int next; //下一条边的编号 int to; //这条边到达的点 int w; } edge[maxm]; int g[maxn],num_edge,n,m,s; int dis[maxn],pre[maxn],team[maxn],head,tail; bool f[maxn]; void add_edge(int from,int to,int w) { //加入一条从from到to的单向边 edge[++num_edge].next=g[from]; g[from]=num_edge; edge[num_edge].to=to; edge[num_edge].w=w; } void init() { int u,v,w; num_edge=0; scanf("%d %d %d",&n,&m,&s);//读入点数和边数 for(int i=1; i<=m; i++) { scanf("%d %d %d",&u,&v,&w); //u、v之间有一条边 add_edge(u,v,w); add_edge(v,u,w); } } void SPFA() { for (int i=1; i<=n; i++) dis[i]=INF; dis[s]=0; head=0; tail=1; team[0]=s; f[s]=true; while(head<tail) { int u=team[head++]; f[u]=false; for (int i=g[u]; i!=0; i=edge[i].next) { int v=edge[i].to; if (dis[v]>dis[u]+edge[i].w) { dis[v]=dis[u]+edge[i].w; pre[v]=u; if (!f[v]) { //队列中不存在v点,v入队。 team[tail++]=v; f[v]=true; } } } } } void dfs(int i) { if(i!=s) dfs(pre[i]); cout<<i<<' '; } void write() { for (int i=1; i<=n; i++) if(i!=s) { dfs(i); cout<<dis[i]<<endl; } } int main() { init(); SPFA(); write(); /*for (int u=1;u<n;u++) { cout<<u<<' '; for (int i=g[u];i!=0;i=edge[i].next) { int v=edge[i].to; cout<<v<<' '; } cout<<endl; }*/ return 0; } /* 5 8 1 1 2 10 1 5 7 1 3 49 2 3 17 2 4 7 2 5 5 3 4 34 4 5 13 */
最小生成树
kruskal
#include<bits/stdc++.h> using namespace std; #define N 105 #define INF 0x3f3f3f3f struct edge { int u; int v; int w; }; struct edge e[N]; int n,m; int f[N]; int sum=0,num=0; int cmp(const edge &a,const edge &b) { if(a.w<b.w) return 1; else return 0; } int getf(int v) { if(f[v] == v) { return v; } else { f[v] = getf(f[v]);//路径压缩 return f[v]; } } int merge(int v,int u) { int t1,t2; t1=getf(v); t2=getf(u); if(t1!=t2) { //不在同一集合 f[t2] = t1; return 1; } return 0; } int main() { int i; cin>>n>>m; for(i=1; i<=m; i++) { cin>>e[i].u>>e[i].v>>e[i].w; } sort(e+1,e+m+1,cmp); //init for(i=1; i<=n; i++) { f[i] = i; } //Kruskal for(i=1; i<=m; i++) { if(merge(e[i].u,e[i].v)) { num++;//选边数 sum=sum+e[i].w;//权值和 } if(num==n-1) break; } cout<<sum; return 0; }
prim
#include<bits/stdc++.h> using namespace std; #define N 105 #define INF 0x3f3f3f3f int main(){ int n,m,i,j,k,min,t1,t2,t3; int e[N][N],dis[N],book[N]={0}; int num=0,sum=0; cin>>n>>m; for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ if(i==j) e[i][j] = 0; else e[i][j] = INF; } } //read for(i=1;i<=m;i++){ cin>>t1>>t2>>t3; e[t1][t2]=t3; e[t2][t1]=t3;//无向图 } for(i=1;i<=n;i++) dis[i]=e[1][i]; //prim book[1] = 1; num++; while(num<n){ min = INF; for(i=1;i<=n;i++){ if(book[i]==0 && dis[i]<min){ min = dis[i]; j = i; } } book[j] = 1; num++; sum += dis[j]; for(k=1;k<=n;k++){ if(book[k] == 0 && dis[k]>e[j][k]){ dis[k] = e[j][k]; } } } cout<<sum; return 0; }
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号