1030—图
Dijkstra+DSF
简单题套代码
DSF记得pop
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
const int INF=1000000;
int g[510][510];
int cost[510][510];
int dis[510];
int vis[510];
int n,m,s,d1;//城市数,公路数,起终点
vector<int>pre[510];
void Dijkstra(int x){//s
fill(dis,dis+510,INF);
dis[x]=0;
for(int i=0;i<n;i++){
int u=-1;
int min=INF;
for(int j=0;j<n;j++){
if(dis[j]<min&&vis[j]==0){
u=j;
min=dis[j];
}
}
if(u==-1)return;
vis[u]=1;
for(int v=0;v<n;v++){
if(g[u][v]!=INF&&vis[v]==0){
if(dis[u]+g[u][v]<dis[v]){
dis[v]=dis[u]+g[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(dis[u]+g[u][v]==dis[v]){
pre[v].push_back(u);
}
}
}
}
}
vector<int>temp,path;
int cost1,mincost=INF;
void DSF(int x){//d1
if(x==s){
temp.push_back(x);
cost1=0;
int size=temp.size();
for(int i=0;i<size-1;i++){
cost1=cost1+cost[temp[i]][temp[i+1]];
}
if(cost1<mincost){
path=temp;
mincost=cost1;
}
temp.pop_back();
return;
}
temp.push_back(x);
for(int i=0;i<pre[x].size();i++){
DSF(pre[x][i]);
}
temp.pop_back();
}
int main(){
fill(g[0],g[0]+510*510,INF);
scanf("%d%d%d%d",&n,&m,&s,&d1);
int a,b,c,d;
for(int i=0;i<m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
g[a][b]=c;
g[b][a]=c;
cost[a][b]=d;
cost[b][a]=d;
}
fill(vis,vis+510,0);
Dijkstra(s);
DSF(d1);
//for(int i=0;i<5;i++)printf("%d ",pre[i].size());
for(int i=path.size()-1;i>=0;i--){
printf("%d ",path[i]);
}
printf("%d %d\n",dis[d1],mincost);
}
1072—图
注意输入数据的提取,m可以取到10
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int INF=1000000000;
int g[1020][1020];
int vis[1020];
int dis[1020];
int n,m,k,ds;
void Dijkstra(int x){
fill(vis,vis+1020,0);
fill(dis,dis+1020,INF);
dis[x]=0;
for(int i=1;i<=n+m;i++){
int u=-1;
int MIN=INF;
for(int j=1;j<=n+m;j++){
if(vis[j]==0&&dis[j]<MIN){
u=j;
MIN=dis[j];
}
}
//printf("u:%d\n",u);
if(u==-1)return;
vis[u]=1;
for(int v=1;v<=n+m;v++){
if(dis[u]+g[u][v]<dis[v]&&vis[v]==0&&g[u][v]!=INF){
dis[v]=dis[u]+g[u][v];
}
}
}
}
int getid(string x){
int ans=0;
for(int i=0;i<x.length();i++){
if(x[i]!='G'){
ans=ans*10+x[i]-'0';
}
}
if(x[0]=='G')return n+ans;
else return ans;
}
int main(){
fill(g[0],g[0]+1020*1020,INF);
scanf("%d%d%d%d",&n,&m,&k,&ds);//房子的数目,candidate的数目,路的数目,辐射范围
string a,b;
int c;
for(int i=0;i<k;i++){
cin>>a>>b>>c;
g[getid(a)][getid(b)]=c;
g[getid(b)][getid(a)]=c;
}
/*for(int i=1;i<n+m+1;i++){
for(int j=1;j<n+m+1;j++){
if(g[i][j]==INF){
printf("- ");
}else{
printf("%d ",g[i][j]);
}
}
printf("\n");
}*/
int pos=-1,temp;
double minmax=-1,avg,minAvg=INF;
for(int i=n+1;i<=n+m;i++){
avg=0;temp=INF;
Dijkstra(i);
/*for(int j=1;j<n+1;j++){
printf("%d\n",dis[j]);
}*/
for(int j=1;j<=n;j++){
avg=avg+dis[j];
if(dis[j]>ds){//超出辐射范围
temp=INF;
break;
}else if(dis[j]<temp){
temp=dis[j];//到某个站的最短距离
}
}
if(temp==INF)continue;
//printf("%d,%d\n",temp,i);
if(temp>minmax){
minmax=temp;
pos=i;
minAvg=avg;
}else if(temp==minmax&&avg<minAvg){
pos=i;
minAvg=avg;
}
//printf("%d,%lf\n\n",pos,avg/n);
}
if(pos==-1){
printf("No Solution\n");
}else{
printf("G%d\n",pos-n);
printf("%.1lf %.1lf\n",minmax,minAvg/n);
}
}
1087—图
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
using namespace std;
const int INF=1000000;
int g[210][210];
int vis[210];
int dis[210];
int happy[210];
vector<int>pre[210];
vector<int> tempPath,path;
int n,k;//城市数,路径数
map<string,int>sti;
map<int,string>its;
void Dijkstra(int x){
fill(vis,vis+210,0);
fill(dis,dis+210,INF);
dis[x]=0;
for(int i=0;i<n;i++){
int u=-1;
int MIN=INF;
for(int j=0;j<n;j++){
if(vis[j]==0&&dis[j]<MIN){
u=j;
MIN=dis[j];
}
}
// printf("u:%d\n",u);
if(u==-1)return;
vis[u]=1;
for(int v=0;v<n;v++){
if(vis[v]==0&&g[u][v]!=INF){
if(dis[u]+g[u][v]<dis[v]){
dis[v]=dis[u]+g[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(dis[u]+g[u][v]==dis[v]){
pre[v].push_back(u);
}
}
}
}
}
int pathNum=0;
int minCost=INF,maxHappiness=0,count1;
void DSF(int x){
if(x==0){
tempPath.push_back(x);
int cost=0,happiness=0;
for(int i=0;i<tempPath.size()-1;i++){//路线是倒序的,终点->起点
cost+=g[tempPath[i]][tempPath[i+1]];
happiness+=happy[tempPath[i]];
}
if(cost<minCost){//计算路径条数
pathNum=1;
}else if(cost==minCost){
pathNum++;
}
if(cost<minCost){//找花费最少的
path=tempPath;
minCost=cost;
maxHappiness=happiness;
count1=tempPath.size()-1;
}else if(cost==minCost&&happiness>maxHappiness){//在花费相同时找happiness大的
path=tempPath;
maxHappiness=happiness;
count1=tempPath.size()-1;
}else if(cost==minCost&&happiness==maxHappiness&&tempPath.size()<count1){//在happiness相同时找路径上城市数少的
path=tempPath;
count1=tempPath.size()-1;
}
tempPath.pop_back();
return;
}
tempPath.push_back(x);
for(int i=0;i<pre[x].size();i++){
DSF(pre[x][i]);
}
tempPath.pop_back();
}
int cityCount=0; //城市数
int change(string a){
if(sti.find(a)==sti.end()){//还未加入
sti[a]=cityCount;
its[cityCount]=a;
return cityCount++;
}else{
return sti[a];
}
}
int main(){
fill(happy,happy+210,0);
fill(g[0],g[0]+210*210,INF);
scanf("%d%d",&n,&k);
string start;
cin>>start;
change(start);
string a,b;
int c;
for(int i=0;i<n-1;i++){
cin>>a>>c;
happy[change(a)]=c;
}
for(int i=0;i<k;i++){
cin>>a>>b>>c;
g[sti[a]][sti[b]]=c;
g[sti[b]][sti[a]]=c;
}
Dijkstra(0);
DSF(sti["ROM"]);
/* for(int i=0;i<n;i++){
printf("%d:",i);
for(int j=0;j<pre[i].size();j++){
printf("%d ",pre[i][j]);
}
printf("\n");
}*/
printf("%d %d %d %d\n",pathNum,minCost,maxHappiness,maxHappiness/count1);
for(int i=path.size()-1;i>=0;i--){
cout<<its[path[i]];
if(i!=0){
cout<<"->";
}
}
printf("\n");
}