几个小模板:topology, dijkstra, spfa, floyd, kruskal, prim
1.topology:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 9 using namespace std; 10 11 #define EPS 1e-6 12 #define ll long long 13 #define INF 0x7fffffff 14 15 const int N=1000; 16 const int N2=2000; 17 int fir[N],next_[N2],u[N2],v[N2]; 18 int du[N]; 19 int n,m; 20 21 void Topology(); 22 23 int main(){ 24 //freopen("D:\\input.in","r",stdin); 25 //freopen("D:\\output.out","w",stdout); 26 scanf("%d%d",&n,&m); 27 for(int i=1;i<=n;i++) fir[i]=-1,du[i]=0; 28 for(int i=1;i<=m;i++){ 29 scanf("%d%d",&u[i],&v[i]); 30 next_[i]=fir[u[i]]; 31 fir[u[i]]=i; 32 du[v[i]]++; 33 } 34 Topology(); 35 return 0; 36 } 37 void Topology(){ 38 int top=-1; 39 for(int i=1;i<=n;i++) 40 if(du[i]==0) du[i]=top,top=i; 41 for(int i=1;i<=n;i++){ 42 if(top==-1){ 43 cout<<"A cycle exists in the graph!"<<endl; 44 return; 45 }else{ 46 int j=top; 47 top=du[top]; 48 cout<<j<<endl; 49 for(int k=fir[j];k!=-1;k=next_[k]){ 50 if(--du[v[k]]==0) 51 du[v[k]]=top,top=v[k]; 52 } 53 } 54 } 55 }
2.dijkstra:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 9 using namespace std; 10 11 #define INF 0x7fffffff 12 13 const int N=1000; 14 const int N2=1000000; 15 int node_num,edge_num,start_node,final_node; 16 int node_first[N],node_next[N2],node_begin[N2],node_end[N2],node_value[N2]; 17 int dis[N],node_fa[N],road[N],road_len; 18 bool b[N]; 19 20 void TheBegin();//初始化 21 void Work();//存储无向图 22 void Dijkstra();//核心算法 23 void Road();//输出最短路径 24 25 int main(){ 26 //freopen("D:\\input.in","r",stdin); 27 //freopen("D:\\output.out","w",stdout); 28 scanf("%d%d%d%d",&node_num,&edge_num,&start_node,&final_node); 29 TheBegin(); 30 Work(); 31 Dijkstra(); 32 Road(); 33 return 0; 34 } 35 void TheBegin(){ 36 for(int i=1;i<=node_num;i++){ 37 node_first[i]=-1; 38 dis[i]=INF; 39 } 40 } 41 void Work(){ 42 for(int i=1;i<=edge_num;i++){ 43 scanf("%d%d%d",&node_begin[i],&node_end[i],&node_value[i]); 44 node_next[i]=node_first[node_begin[i]]; 45 node_first[node_begin[i]]=i; 46 node_begin[i+edge_num]=node_end[i]; 47 node_end[i+edge_num]=node_begin[i]; 48 node_value[i+edge_num]=node_value[i]; 49 node_next[i+edge_num]=node_first[node_begin[i+edge_num]]; 50 node_first[node_begin[i+edge_num]]=i+edge_num; 51 } 52 } 53 void Dijkstra(){ 54 dis[start_node]=0; 55 for(int k=1;k<=node_num;k++){ 56 int x,m=INF; 57 for(int i=1;i<=node_num;i++) 58 if(!b[i]&&dis[i]<m) m=dis[x=i]; 59 b[x]=1; 60 for(int i=node_first[x];i!=-1;i=node_next[i]){ 61 if(!b[node_end[i]]&&dis[node_end[i]]>dis[x]+node_value[i]){ 62 dis[node_end[i]]=dis[x]+node_value[i]; 63 node_fa[node_end[i]]=x; 64 } 65 } 66 } 67 printf("%d\n",dis[final_node]); 68 } 69 void Road(){ 70 for(int i=final_node;i!=start_node;i=node_fa[i]) road[road_len++]=i; 71 printf("the shortest road is:%d",start_node); 72 for(int i=road_len-1;i>=0;i--) printf("-->%d",road[i]); 73 puts(""); 74 }
3.dijkstra堆优化:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <queue> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdlib> 9 10 using namespace std; 11 12 #define INF 0x7fffffff 13 14 const int N=1000; 15 const int N2=1000000; 16 int node_num,edge_num,start_node,final_node; 17 int node_first[N],node_next[N2],node_begin[N2],node_end[N2],node_value[N2]; 18 int dis[N],node_fa[N],road[N],road_len; 19 bool b[N]; 20 typedef pair<int,int> pii; 21 priority_queue<pii,vector<pii>,greater<pii> >pq; 22 23 void TheBegin();//初始化 24 void Work();//存储无向图 25 void Dijkstra();//核心算法 26 void Road();//输出最短路径 27 28 int main(){ 29 //freopen("D:\\input.in","r",stdin); 30 //freopen("D:\\output.out","w",stdout); 31 scanf("%d%d%d%d",&node_num,&edge_num,&start_node,&final_node); 32 TheBegin(); 33 Work(); 34 Dijkstra(); 35 Road(); 36 return 0; 37 } 38 void TheBegin(){ 39 for(int i=1;i<=node_num;i++){ 40 node_first[i]=-1; 41 dis[i]=INF; 42 } 43 } 44 void Work(){ 45 for(int i=1;i<=edge_num;i++){ 46 scanf("%d%d%d",&node_begin[i],&node_end[i],&node_value[i]); 47 node_next[i]=node_first[node_begin[i]]; 48 node_first[node_begin[i]]=i; 49 node_begin[i+edge_num]=node_end[i]; 50 node_end[i+edge_num]=node_begin[i]; 51 node_value[i+edge_num]=node_value[i]; 52 node_next[i+edge_num]=node_first[node_begin[i+edge_num]]; 53 node_first[node_begin[i+edge_num]]=i+edge_num; 54 } 55 } 56 void Dijkstra(){ 57 dis[start_node]=0; 58 pq.push(make_pair(dis[start_node],start_node)); 59 while(!pq.empty()){ 60 pii tmp=pq.top(); 61 pq.pop(); 62 int x=tmp.second; 63 if(b[x]) continue; 64 b[x]=1; 65 for(int i=node_first[x];i!=-1;i=node_next[i]){ 66 if(!b[node_end[i]]&&dis[node_end[i]]>dis[x]+node_value[i]){ 67 dis[node_end[i]]=dis[x]+node_value[i]; 68 pq.push(make_pair(dis[node_end[i]],node_end[i]));//队列里可能会加入重复元素 69 node_fa[node_end[i]]=x; 70 } 71 } 72 } 73 printf("%d\n",dis[final_node]); 74 } 75 void Road(){ 76 for(int i=final_node;i!=start_node;i=node_fa[i]) road[road_len++]=i; 77 printf("the shortest road is:%d",start_node); 78 for(int i=road_len-1;i>=0;i--) printf("-->%d",road[i]); 79 puts(""); 80 }
4.spfa:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <queue> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdlib> 9 10 using namespace std; 11 12 #define INF 0x7fffffff 13 14 const int N=1000; 15 const int N2=1000000; 16 int node_num,edge_num,start_node,final_node; 17 int node_first[N],node_next[N2],node_begin[N2],node_end[N2],node_value[N2]; 18 int dis[N],node_fa[N],road[N],road_len; 19 bool b[N]; 20 queue<int> q; 21 22 void TheBegin();//初始化 23 void Work();//存储无向图 24 void Spfa();//核心算法 25 void Road();//输出最短路径 26 27 int main(){ 28 //freopen("D:\\input.in","r",stdin); 29 //freopen("D:\\output.out","w",stdout); 30 scanf("%d%d%d%d",&node_num,&edge_num,&start_node,&final_node); 31 TheBegin(); 32 Work(); 33 Spfa(); 34 Road(); 35 return 0; 36 } 37 void TheBegin(){ 38 for(int i=1;i<=node_num;i++){ 39 node_first[i]=-1; 40 dis[i]=INF; 41 } 42 } 43 void Work(){ 44 for(int i=1;i<=edge_num;i++){ 45 scanf("%d%d%d",&node_begin[i],&node_end[i],&node_value[i]); 46 node_next[i]=node_first[node_begin[i]]; 47 node_first[node_begin[i]]=i; 48 node_begin[i+edge_num]=node_end[i]; 49 node_end[i+edge_num]=node_begin[i]; 50 node_value[i+edge_num]=node_value[i]; 51 node_next[i+edge_num]=node_first[node_begin[i+edge_num]]; 52 node_first[node_begin[i+edge_num]]=i+edge_num; 53 } 54 } 55 void Spfa(){ 56 dis[start_node]=0; 57 q.push(start_node); 58 while(!q.empty()){ 59 int x=q.front(); 60 q.pop(); 61 b[x]=0; 62 for(int i=node_first[x];i!=-1;i=node_next[i]){ 63 if(dis[node_end[i]]>dis[x]+node_value[i]){ 64 dis[node_end[i]]=dis[x]+node_value[i]; 65 node_fa[node_end[i]]=x; 66 if(!b[node_end[i]]){ 67 q.push(node_end[i]); 68 b[node_end[i]]=1; 69 } 70 } 71 } 72 } 73 printf("%d\n",dis[final_node]); 74 } 75 void Road(){ 76 for(int i=final_node;i!=start_node;i=node_fa[i]) road[road_len++]=i; 77 printf("the shortest road is:%d",start_node); 78 for(int i=road_len-1;i>=0;i--) printf("-->%d",road[i]); 79 puts(""); 80 }
5.floyd:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 9 using namespace std; 10 11 #define INF 0x7fffffff 12 13 const int N=1000; 14 const int N2=1000000; 15 int node_num,edge_num,ans_num; 16 int dp[N][N]; 17 18 int main() 19 { 20 //freopen("D:\\input.in","r",stdin); 21 //freopen("D:\\output.out","w",stdout); 22 int u,v,w; 23 scanf("%d%d",&node_num,&edge_num); 24 for(int i=1;i<=node_num;i++) 25 for(int j=1;j<=node_num;j++) 26 dp[i][j]=(i==j?0:INF); 27 for(int i=1;i<=edge_num;i++) 28 { 29 scanf("%d%d%d",&u,&v,&w); 30 dp[u][v]=w; 31 dp[v][u]=w; 32 } 33 for(int k=1;k<=node_num;k++) 34 for(int i=1;i<=node_num;i++) 35 for(int j=1;j<=node_num;j++) 36 if(dp[i][k]!=INF&&dp[k][j]!=INF) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]); 37 scanf("%d",&ans_num); 38 for(int i=1;i<=ans_num;i++) 39 { 40 scanf("%d%d",&u,&v); 41 printf("%d->%d: %d\n",u,v,dp[u][v]); 42 } 43 return 0; 44 }
6.kruskal(并查集):
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 9 using namespace std; 10 11 #define EPS 1e-6 12 #define ll long long 13 #define INF 0x7fffffff 14 15 const int N=1000; 16 const int N2=1000000; 17 int node_num,edge_num; 18 int node_u[N2],node_v[N2],node_w[N2],p[N],r[N2]; 19 20 inline int cmp(const int &a,const int &b) { return node_w[a]<node_w[b]; } 21 inline int find(int x) { return p[x]==x?x:p[x]=find(p[x]); } 22 int Kruskal(); 23 24 int main(){ 25 //freopen("D:\\input.in","r",stdin); 26 //freopen("D:\\output.out","w",stdout); 27 scanf("%d%d",&node_num,&edge_num); 28 for(int i=1;i<=edge_num;i++) 29 scanf("%d%d%d",&node_u[i],&node_v[i],&node_w[i]); 30 printf("%d\n",Kruskal()); 31 return 0; 32 } 33 int Kruskal(){ 34 int ans=0; 35 for(int i=1;i<=node_num;i++) p[i]=i; 36 for(int i=1;i<=edge_num;i++) r[i]=i; 37 sort(&r[1],&r[edge_num+1],cmp); 38 for(int i=1;i<=edge_num;i++){ 39 int e=r[i]; 40 int x=find(node_u[e]); 41 int y=find(node_v[e]); 42 if(x!=y) ans+=node_w[e],p[x]=y; 43 } 44 return ans; 45 }
7.prim:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 9 using namespace std; 10 11 #define EPS 1e-6 12 #define ll long long 13 #define INF 0x7fffffff 14 15 const int N=1000; 16 int a[N][N],distance_[N],node_num,edge_num; 17 bool choose[N]; 18 19 int Prim(); 20 21 int main(){ 22 //freopen("D:\\input.in","r",stdin); 23 //freopen("D:\\output.out","w",stdout); 24 int u,v,w; 25 scanf("%d%d",&node_num,&edge_num); 26 for(int i=1;i<=node_num;i++) 27 for(int j=1;j<=node_num;j++) 28 a[i][j]=(i==j?0:INF); 29 for(int i=1;i<=edge_num;i++){ 30 scanf("%d%d%d",&u,&v,&w); 31 a[u][v]=w; 32 a[v][u]=w; 33 } 34 printf("%d\n",Prim()); 35 return 0; 36 } 37 int Prim(){ 38 int ans=0; 39 for(int i=1;i<=node_num;i++) choose[i]=0,distance_[i]=INF; 40 distance_[1]=0; 41 for(int i=1;i<=node_num;i++){ 42 int x=-1; 43 for(int j=1;j<=node_num;j++) 44 if(!choose[j]) 45 if(x==-1) x=j; 46 else if(distance_[j]<distance_[x]) x=j; 47 choose[x]=1; 48 ans+=distance_[x]; 49 for(int j=1;j<=node_num;j++) 50 if(!choose[j]&&a[x][j]!=INF){ 51 distance_[j]=min(distance_[j],a[x][j]); 52 } 53 } 54 return ans; 55 }
8.prim堆优化:
1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 #include <queue> 9 10 using namespace std; 11 12 #define EPS 1e-6 13 #define ll long long 14 #define INF 0x7fffffff 15 16 const int N=1000; 17 const int N2=1000000; 18 int distance_[N],node_num,edge_num; 19 int node_first[N],node_next[N2],node_u[N2],node_v[N2],node_w[N2]; 20 bool choose[N]; 21 struct cmp{ 22 bool operator()(const int &a,const int &b) const{ 23 return distance_[a]>distance_[b]; 24 } 25 }; 26 priority_queue<int,vector<int>,cmp> pq; 27 28 int prim(); 29 30 int main(){ 31 //freopen("D:\\input.in","r",stdin); 32 //freopen("D:\\output.out","w",stdout); 33 scanf("%d%d",&node_num,&edge_num); 34 for(int i=1;i<=node_num;i++) 35 node_first[i]=-1; 36 for(int i=1;i<=edge_num;i++){ 37 scanf("%d%d%d",&node_u[i],&node_v[i],&node_w[i]); 38 node_next[i]=node_first[node_u[i]]; 39 node_first[node_u[i]]=i; 40 node_u[i+edge_num]=node_v[i]; 41 node_v[i+edge_num]=node_u[i]; 42 node_w[i+edge_num]=node_w[i]; 43 node_next[i+edge_num]=node_first[node_u[i+edge_num]]; 44 node_first[node_u[i+edge_num]]=i+edge_num; 45 } 46 printf("%d\n",prim()); 47 return 0; 48 } 49 int prim(){ 50 int ans=0; 51 for(int i=1;i<=node_num;i++) choose[i]=0,distance_[i]=INF; 52 distance_[1]=0; 53 pq.push(1); 54 while(!pq.empty()){ 55 int x=pq.top(); 56 pq.pop(); 57 if(choose[x]) continue; 58 choose[x]=1; 59 ans+=distance_[x]; 60 for(int i=node_first[x];i!=-1;i=node_next[i]) 61 if(!choose[node_v[i]]){ 62 if(distance_[node_v[i]]>node_w[i]){ 63 distance_[node_v[i]]=node_w[i]; 64 pq.push(node_v[i]); 65 } 66 } 67 } 68 return ans; 69 }