注:以下所有代码都没有在oj上提交,但是样例可以通过,如有错误,欢迎指正
文章目录
问题 A: 图的最小生成树-Prim算法
#include <bits/stdc++.h>
using namespace std;
int w[110][110];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> w[i][j];
}
}
for (int j = 0; j < n; j++)
{
if (w[0][j] == 0)
{
printf("%d - -\n", j);
}
else
{
printf("%d %d %d\n", j, w[0][j], 0);
}
}
return 0;
}
问题 B: 图的最小生成树-Kruskal算法
#include <bits/stdc++.h>
using namespace std;
int n;
int w[110][110];
struct p
{
int from,to,val;
};
vector<p>edge;
int main(){
int n;
cin>>n;
for( int i=0;i<n;i++){
for( int j=0;j<n;j++){
cin>>w[i][j];
if(w[i][j]==0) continue;
edge.push_back((p){i,j,w[i][j]});
}
}
for( int i=0;i<edge.size();i++){
for( int j=i+1;j<edge.size();j++){
if(edge[i].val>edge[j].val) swap(edge[j],edge[i]);
}
}
for( int i=0;i<edge.size();i++){
printf("<%d,%d>:%d\n",edge[i].from,edge[i].to,edge[i].val);
}
return 0;
}
问题 C: 算法7-9:最小生成树
#include <bits/stdc++.h>
using namespace std;
const int N=60,inf=0x3f3f3f3f;
int w[N][N];
int prim(int n){
int vis[60]={};
int dist[60];
int res=0;
memset(dist,0x3f,sizeof(dist));
vis[0]=1;
dist[0]=0;
int now=0;
for( int i=0;i<n-1;i++){
for( int j=0;j<n;j++){
if(w[now][j]==0||vis[j]==1) continue;
dist[j]=min(dist[j],w[now][j]);
}
int ne=0;
int minn=inf;
for( int j=0;j<n;j++){
if(vis[j])continue;
if(dist[j]<minn){
minn=dist[j];
ne=j;
}
}
res+=dist[ne];
now=ne;
vis[ne]=1;
}
return res;
}
int main(){
int n;
cin>>n;
for( int i=0;i<n;i++){
for( int j=0;j<n;j++){
cin>>w[i][j];
}
}
cout<<prim(n)<<endl;
return 0;
}
问题 D: 算法7-15:迪杰斯特拉最短路径算法
#include <bits/stdc++.h>
using namespace std;
const int N=60,inf=0x3f3f3f3f;
int w[N][N];
int dist[N];
void dijistra(int n,int be){
memset(dist,0x3f,sizeof(dist));
int vis[N]={};
vis[be]=1;
dist[be]=0;
int now=be;
for( int i=0;i<n-1;i++){
for( int j=0;j<n;j++){
if(w[now][j]==0||vis[j]==1) continue;
dist[j]=min(dist[j],dist[now]+w[now][j]);
}
int ne=0,minn=inf;
for( int j=0;j<n;j++){
if(vis[j]==1) continue;
if(dist[j]<minn){
minn=dist[j];
ne=j;
}
}
now=ne;
vis[ne]=1;
}
return ;
}
int main(){
int n;
int be;
cin>>n>>be;
for( int i=0;i<n;i++){
for( int j=0;j<n;j++){
cin>>w[i][j];
}
}
dijistra(n,be);
for( int i=0;i<n;i++){
if(i==be) continue;
else cout<<dist[i]<<" ";
}
return 0;
}
问题 E: 图的最短路径-Floyd算法输出最短路径包含的边
#include <bits/stdc++.h>
using namespace std;
const int N=110,inf=0x3f3f3f3f;
struct p{
int len,mid;
}w[N][N];
int main(){
int n;
cin>>n;
for( int i=0;i<n;i++){
for( int j=0;j<n;j++){
cin>>w[i][j].len>>w[i][j].mid;
}
}
int be,en;
cin>>be>>en;
stack<int>ans;
cout<<w[be][en].len<<endl;
while(true){
ans.push(en);
if(en==be) break;
en=w[be][en].mid;
}
while(!ans.empty()){
cout<<ans.top()<<" ";
ans.pop();
}
return 0;
}
问题 F: 案例6-1.5:旅游规划
#include <bits/stdc++.h>
using namespace std;
const int N=510,inf=0x3f3f3f3f;
int h[N],ne[N*N],to[N*N],val[N*N],cost[N*N],cnt;
此处应为N*N,上一个版本写成N*2,现已修正
int n,m,s,d;
void add( int a,int b,int c,int d){
cost[cnt]=d,val[cnt]=c,to[cnt]=b,ne[cnt]=h[a],h[a]=cnt++;
}
int dist[N];
int sum_cost[N];
void dijistra( int be){
memset(dist,0x3f,sizeof(dist));
memset(sum_cost,0x3f,sizeof(sum_cost));
int vis[N]={};
dist[be]=0;
vis[be]=1;
sum_cost[be]=0;
int now=be;
for( int i=0;i<n-1;i++){
// cout<<now<<endl;
for( int j=h[now];j!=-1;j=ne[j]){
int k=to[j];
if(vis[k]) continue;
if(dist[k]>dist[now]+val[j]){
dist[k]=dist[now]+val[j];
sum_cost[k]=sum_cost[now]+cost[j];
}
else if(dist[k]==dist[now]+val[j]){
sum_cost[k]=min(sum_cost[k],sum_cost[now]+cost[j]);
}
}
int ne=0,min_dist=inf,min_cost=inf;
for( int j=0;j<n;j++){
if(vis[j]) continue;
if(dist[j]<min_dist){
min_dist=dist[j];
min_cost=sum_cost[j];
ne=j;
}
else if(dist[j]==min_dist&&sum_cost[j]<min_cost){
min_cost=sum_cost[j];
ne=j;
}
}
vis[ne]=1;
now=ne;
}
}
int main(){
memset(h,-1,sizeof(h));
cin>>n>>m>>s>>d;
for( int i=1;i<=m;i++){
int a,b,c,d;
cin>>a>>b>>c>>d;
add(a,b,c,d);
add(b,a,c,d);
}
dijistra(s);
cout<<dist[d]<<" "<<sum_cost[d]<<endl;
return 0;
}
问题 G: 案例6-1.7:公路村村通
#include <bits/stdc++.h>
using namespace std;
const int N=1010,inf=0x3f3f3f3f;
struct edge{
int from,to,val;
};
vector<edge>e;
int fa[N];
int find( int x){
if(x!=fa[x]) fa[x]=find(fa[x]);
return fa[x];
}
void merge( int x,int y){
if(find(x)!=find(y)){
fa[find(x)]=find(y);
}
}
bool cmp(edge a,edge b){
return a.val<b.val;
}
int check(int n){
for( int i=1;i<=n;i++){
if(find(i)!=find(1)) return 0;
}
return 1;
}
int main(){
int n,m;
cin>>n>>m;
for( int i=0;i<=n;i++) fa[i]=i;
for( int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
e.push_back((edge){a,b,c});
}
sort(e.begin(),e.end(),cmp);
int ans=0;
for( int i=0;i<e.size();i++){
if(find(e[i].from)!=find(e[i].to)){
merge(e[i].from,e[i].to);
ans+=e[i].val;
}
}
if(check(n)==0) {
cout<<-1<<endl;
}
else cout<<ans<<endl;
return 0;
}
问题 H: 基础实验6-2.5:城市间紧急救援
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f,N=510;
int n,m,s,d;
int w[N][N];
int call_num[N],path_num[N];
int pre[N],num[N];
void dijistra(){
int vis[510],dist[510];
memset(dist,0x3f,sizeof(dist));
memset(pre,-1,sizeof(pre));
vis[s]=1;
dist[s]=0;
call_num[s]=num[s];
path_num[s]=1;
int now=s;
for( int i=1;i<n;i++){
for( int j=0;j<n;j++){
if(w[now][j]==0||vis[j]==1) continue;
if(dist[j]>dist[now]+w[now][j]){
dist[j]=dist[now]+w[now][j];
call_num[j]=call_num[now]+num[j];
path_num[j]=path_num[now];
pre[j]=now;
}
else if(dist[j]==dist[now]+w[now][j]){
if(call_num[j]<call_num[now]+num[j]){
call_num[j]=max(call_num[j],call_num[now]+num[j]);
pre[j]=now;
}
path_num[j]+=path_num[now];
}
}
int minn=inf,ne=0;
for( int j=0;j<n;j++){
if(vis[j]==1) continue;
if(dist[j]<minn){
minn=dist[j];
ne=j;
}
else if(dist[j]==minn&&num[j]>num[ne]){
ne=j;
}
}
vis[ne]=1;
now=ne;
}
}
int main(){
cin>>n>>m>>s>>d;
for( int i=0;i<n;i++) cin>>num[i];
for( int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
w[a][b]=c;
w[b][a]=c;
}
dijistra();
stack<int>ans;
cout<<path_num[d]<<" "<<call_num[d]<<endl;
上面这句话位置写错,原来写在了while下面,现在已经修正
while(d!=-1&&d!=s){
ans.push(d);
d=pre[d];
}
cout<<d<<" ";
while(!ans.empty()){
cout<<ans.top()<<" ";
ans.pop();
}
return 0;
}