最小生成树
//prim 算法 #include#include using namespace std; int mp[3003][3003]; int vis[3003],d[3003]; int n,m; void prim(){ memset(d,0x3f,sizeof d); memset(vis,0,sizeof vis); d[1] = 0; for(int i=1;i int x = 0; for(int j=1;j<=n;j++){ if(!vis[j] && d[j] < d[x]) x = j; } vis[x] = 1; for(int j=1;j<=n;j++){ if(!vis[j]){ d[j] = min(mp[j][x],d[j]); } } } } int main(){ memset(mp,0x3f,sizeof mp); int ans = 0,cnt = 0; cin >> n >> m; for(int i=1;i<=n;i++){ mp[i][i] = 0; } for(int i=1;i<=m;i++){ int u,v,w; cin >> u >> v >> w; mp[u][v] = mp[v][u] = min(mp[u][v],w); } prim(); for(int i=2;i<=n;i++){ if(d[i]){ cnt++; if(ans < d[i]){ ans = d[i]; } } } cout << cnt << " " << ans; }
//kruscal算法 //1.并查集写 其实书上也是用到了并查集没明说而已 #include#include #include using namespace std; const int maxn = 1e5+5; struct Edge{ int u,v,w; bool operator < (const Edge & e)const{ return w < e.w; // 重载< 运算符 } }e[maxn];//内存绝对够 int fa[maxn]; // 判断是不是在一个连通分量 int find(int x){ if(fa[x] != x) fa[x] = find(fa[x]); // 路径压缩 return fa[x]; } void merge(int a,int b){ int x = find(a); int y = find(b); fa[x] = y; } int main(){ int n,m; int ans = 0 , cnt = 0; cin >> n >> m; for(int i=1;i<=n;i++){ fa[i] = i ; // 预处理下 } for(int i=1;i<=m;i++){ int u,v,w; cin >> u >> v >> w; e[i].u = u, e[i].v = v,e[i].w = w; } sort(e+1,e+1+m) ;// 也可以用冒泡排序这里就不多写了 for(int i=1;i<=m;i++){ int u = e[i].u; int v = e[i].v; if(find(u) != find(v)){ merge(u,v); cnt++; ans = e[i].w; } } cout << cnt << " " << ans ; }
//dfs判断环 #include#include #include #include using namespace std; const int maxn = 1e5 + 5; int n, m; int vis[maxn]; // 判断有没有被选 int vis2[maxn]; int ans = 0, cnt = 0,flag = 0; vector son[maxn]; struct Edge { int u, v, w; bool operator < (const Edge & e)const { return w < e.w; // 重载< 运算符 } } e[maxn]; //内存绝对够 void dfs(int u,int v1){ for(int i=0;i int v = son[u][i]; if(vis2[v]) continue; vis2[v] = 1; if(vis[v]){ if(v == v1){ flag = 1; return; } else if(!flag){ dfs(v,v1); } } } } void kruscal() { for(int i=1;i<=m;i++){ int u = e[i].u; int v = e[i].v; memset(vis2,0,sizeof vis2); dfs(u,v); if(!flag && (!vis[u]||!vis[v])){ vis[u] = vis[v] = 1; cnt++; ans = e[i].w; } flag = 0; } } int main() { memset(vis, 0, sizeof vis); cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; son[u].push_back(v); son[v].push_back(u); e[i].u = u, e[i].v = v, e[i].w = w; } sort(e + 1, e + 1 + m) ; // 也可以用冒泡排序这里就不多写了 kruscal(); cout << cnt << " " << ans; }
//1.普通dijstra算法 #include#include #include using namespace std; const int maxn = 1e6 + 5; struct Edge{ int to,next,w; }; Edge edge[maxn]; int d[maxn]; int vis[maxn], cnt = 0; int n, m,head[maxn]; void add(int u,int v,int w){ edge[++cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt; } void dijstra() { for (int i = 1; i <= n - 1; i++) { int x = 0; for(int j = 1; j <= n; j++) if(!vis[j] && (x == 0 || (d[x] > d[j]))) x= j; vis[x] = 1; for(int i=head[x];i;i=edge[i].next){ int v = edge[i].to; d[v] = min(d[v],d[x] + edge[i].w); } } } int main() { memset(d, 0x3f, sizeof(d)); memset(vis, 0, sizeof(vis)); cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; add(u,v,w); add(v,u,w); } d[1] = 0; dijstra(); cout << d[n]; } //2.堆优化的dijstra算法 #include using namespace std; #include #include #include #include const int maxn = 1e4+5; int d[maxn],vis[maxn]; struct edge{ int v; int w; }; vector son[maxn]; struct node{ int dis,u; }; bool operator > (const node &a,const node& b) { return a.dis > b.dis; } priority_queue ,greater > q; void dijstra(int s){ d[s] = 0; vis[s] = 0; q.push({0,s}); while(!q.empty()){ node t = q.top(); q.pop(); int u = t.u; if(vis[u]){ continue; } for(int i=0;i int v = son[u][i].v; int w = son[u][i].w; if(d[v] > d[u] + w){ d[v] = d[u] + w; q.push({d[v],v}); } } } } int main(){ int n,m; cin >> n >> m; for(int i=1;i<=m;i++){ int u,v,w; cin >> u >> v >> w; son[u].push_back({v,w}); son[v].push_back({u,w}); } memset(d,63,sizeof(d)); memset(vis,0,sizeof(vis)); dijstra(1); cout << d[n] ; } //3.spfa算法 //队列写法 #include using namespace std; #include #include const int maxn = 1e6+5; struct Edge{ int to,next,w; }; Edge edge[maxn]; int vis[maxn],n,m,d[maxn],cnt = 0; int head[maxn]; queue q; void add(int u,int v,int w){ edge[++cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt; } void spfa(){ memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); d[1] = 0; vis[1] = 1; q.push(1); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = 0; for(int i=head[u];i;i = edge[i].next){ int v = edge[i].to; if( d[v] > d[u] + edge[i].w ){ d[v] = d[u] + edge[i].w; if(!vis[v]) q.push(v); } } } } int main(){ cin >> n >> m; for(int i=1;i<=m;i++){ int u,v,w; cin >> u >> v >> w; add(u,v,w); add(v,u,w); } spfa(); cout << d[n]; } //4.floyd算法 只是费时间而已 #include #include using namespace std; int d[1000][1000]; int n,m; int main(){ cin >> n >> m; 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; scanf("%d %d %d",&u,&v,&w); d[u][v] = min(d[u][v],w); } for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ d[i][j] = min(d[i][j],d[i][k] + d[k][j]); } } } cout << d[1][n]; }



