pat-1072

有一个测试点没过,方向偏的有点厉害,不弄了就吸取一下里面的教训吧 

//只看点数即可不要去看边数邻接矩阵法适用于稠密图,只要1000之内,用邻接表即可 
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
const int inf=1000000000; 
int _1,_2,m,range,distt,dsr[1010],visit[1010],t1,t2,index;
double avs[1010]={0},sum;
vector<int> pre[1010];
vector<double>minn,maxx;//找最大是判断是否有solution //vector入错类型会入不进去 
string lll,rrr;
map<int,int>si;
map<int,int>is;
struct node{
	int rr,dist;
};
vector<node>v[1010];
void out(){
     index=0; 
     for(int j=0;j<minn.size();j++){
     	if(maxx[j]>range)minn[j]=-1;
	 }
	for(int i=0;i<minn.size();i++){
		if(minn[index]<minn[i]){
			index=i;
		}
		else if(minn[index]==minn[i]&&avs[index]>avs[i]){
			index=i;
		}
		else if(minn[index]==minn[i]&&avs[index]==avs[i]&&index>i){
			index=i;
		}
	}
	if(minn[index]==-1) printf("No Solution");
	else {
		printf("G%d\n",index+1);
		printf("%.1lf %.1lf",minn[index],avs[index]);//第一个标弄错 minn声明的是int(注意) 
	}
	
}
int main(){
	cin>>_1>>_2>>m>>range;
	for(int i=1;i<=_2;i++){
		si[i]=_1+i;
		//is[_1+i]=[i];//输出时要带G 
	}
	for(int i=0;i<m;i++){
		cin>>lll>>rrr>>distt;
		if(lll[0]=='G'){//string 的单字母是char型 
		  t1=si[stoi(lll.substr(1))];//变量.substr 
		}
		else t1=stoi(lll);
		if(rrr[0]=='G'){
			t2=si[stoi(rrr.substr(1))];
		}
		else t2=stoi(rrr);
		
		v[t1].push_back({t2,distt});
		v[t2].push_back({t1,distt});//太大了邻接表 
	}
	for(int p=1;p<=_2;p++){
	sum=0;
	//fill(avs,avs+1010,1000000000.0);(过度重置将上一次值也覆盖)
	fill(dsr,dsr+1010,inf);
	fill(visit,visit+1010,0);
	dsr[si[p]]=0;
	int n=_1+_2;
	for(int i=0;i<n;i++){
		int u=-1,min=inf;
		for(int j=1;j<=n;j++){
			if(visit[j]==0&&dsr[j]<min){
				min=dsr[j];
				u=j;
			}
		}
		if(u==-1) break;
		visit[u]=1;
		for(int a=0;a<v[u].size();a++){
		node tempp=v[u][a];
		if(visit[tempp.rr]==0){
			if(dsr[u]+tempp.dist<dsr[tempp.rr]){
				dsr[tempp.rr]=dsr[u]+tempp.dist;
				pre[tempp.rr].clear();
				pre[tempp.rr].push_back(u);
			}
			if(dsr[u]+tempp.dist==dsr[tempp.rr]){
				pre[tempp.rr].push_back(u);
			}
		}
		}
	}
	int ttt=inf;int temppp=0;
	for(int q=1;q<=_1;q++){
	
	if(dsr[q]<ttt) ttt=dsr[q];	
	}
	//debug
	//for(int i=1;i<=_1;i++){
	//	printf("%d ",dsr[i]);
	//		}
	//printf("\n");
	//printf("%d\n",ttt);
	minn.push_back(ttt);//如果直接循环找值就不用想数据存储的的事了 (注意) 
	for(int l=1;l<=_1;l++){
		sum+=1.0*dsr[l];
	}
	avs[p-1]= sum/(_1);
	//debug
	//printf("%f %d",avs[p-1],sum); //3.25??
	for(int ll=1;ll<=_1;ll++){
		
		if(dsr[ll]>temppp){
			temppp=dsr[ll];//ll 写成11以后拒绝这种错误命名时尽量避免一些与数字非常像的字母ll啦(注意) 
		
		}
	}
	
	maxx.push_back(temppp);
	
    }
    	//debug
	//for(int i=0;i<minn.size();i++) 
	//printf("%d ",minn[i]);
    out();
    return 0;
}

总结:1.不要使用ll  容易和11混用

2.这是一个多源对比,不是单源多种情况,一开始判断失误,导致浪费了好多精力,想清楚结果到底需要什么如果n可以确定平均就不用dfs了

3.条件过度重置,导致前一次结果覆盖后一次

4.如果只是找最值,尽量能在不存储结果的情况下进行寻找,更简单不易出错

5.申请的变量类型,和要出输出的类型不一致,自然输出是0

6.想的太复杂不就找那几个量吗

结点小于等于1000个要用邻接矩阵 不要管边的个数适用于稠密图

英语无

问题dijkstra算法写的慢要多写写各种形式的把握准确

猜你喜欢

转载自blog.csdn.net/m0_45359314/article/details/112915131