题目详情
先来嚷嚷一波:这个题给的样例有问题!!那个3.3其实应该是3.2!
可是。。。咋就这么多测试点没过
给大伙秀一波惨案
零零散散的正确错误的
俺debug了好久啊呜呜呜,会有人感谢我的!!!
喔对了,其实如果零零散散正确错误的应该是代码细节有问题,你就得再读读题看看是不是有哪个变量写错了呀or是不是哪个细节处理错了。如果有大小比较的一定要再看看~有没有赋值就赋一半的?之类的。
如果是前几个对了后面的全错,请考虑数据范围please!!
这个题数据范围是1000+10不过你读入数据的时候也要注意, 不能getchar搞定啊!它可能不是一位数啊!(测试点四就是这样)用string搞起!
咱讲究图文并茂:
然后好好审题,这个题的第一标尺可不是总路径最近,而是距离最近的那个点最远
就是说每个加油站跑完最短路找距离最近的那个house,然后所有加油站比比找这个点最远的。
最近的最远....第二三个测试点错的小朋友看过来!
看看这段代码:
就是如果d[j]比那个D大,那就求all,能更新本次最小值就更新
如果不大,,,那本次最小值为INF(这是一个很大的数)
这里有什么问题呢?
最小值不合法就弄个最大的数,看起来真的没有问题。
(这个地方卡了本菜鸡很久,并且一度以为是测评机坏掉了QAQ)
但是啊,你底下是不是要求这个最小值的最大值啊?
你这直接赋值个最大,怎么判断minloc不合法啊,,,
所以改进的话就是把刚刚不合法赋值INF的地方赋值一个最小值,然后这里再判断一遍
然后二三样例就过了,,,,
这个题除了这里卡我了一下,再提几个注意点:
- 首先你得注意跑最短路的时候是可以以别的加油站点为中介的(所以是M+N个点)
- 跑多个dij别忘记每次赋值(for个1024下真的时间不长,,不会TLE放心)
你都跑多个dij了还怕TLE???? - 这个题给的样例有问题!!那个3.3其实应该是3.2
这个题不需要四舍五入的(如果四舍五入就是+0.05)没必要
wa了二三测试点的代码(铭记历史才能勇往直前(狗头))
#include<vector>
#include<iostream>
#include <algorithm>
#include <cmath>
#include<map>
#include <queue>
#include <stack>
#include<string.h>
using namespace std;
const int INF=100000;
int G[1024][1024];
//直接把两个存在一起 1~1000 1001~1010
int M,N,K,D;
int d[1024];
double minloc;
int vis[1024];
double gas_all=INF;
double gas_min=-1;
void init(){
for (int i = 0; i <1024 ; ++i) {
for (int j = 0; j < 1024; ++j) {
G[i][j]=INF;
G[j][i]=INF;
}
}
}
void init_dij(){
for (int i = 0; i <= M+N; ++i) {
d[i]=INF;
vis[i]=0;
}
}
int get_one(){
int u=0;
string p;
cin>>p;//输入不能用char,可能会出现G11,199这样的数字
if(p[0]=='G'){
for(int j=1;j<p.length();j++){
u=u*10+p[j]-'0';
}
u+=M;
}else{
for(int j=0;j<p.length();j++){
u=u*10+p[j]-'0';
}
}
return u;
}
//d数组就是到每个点的距离了,其实这里都不需要存路径,,,用d直接说事就行了,反正d已经是最短路
void dij(int v){
init_dij();//d需要更新
d[v]=0;
for (int i = 1; i <= M+N; ++i) {
int u=-1,MIN=INF;
for (int j = 1; j <= M+N ; ++j) {
if(vis[j]==0 && d[j]<MIN){
u=j;
MIN=d[j];
}
}
if(u==-1) return ;
vis[u]=1;
for (int j = 1; j <= M+N ; ++j) {
if(vis[j]==0 && G[j][u]!=INF ){
if(d[j]>d[u]+G[j][u]){
d[j]=d[u]+G[j][u];
}
}
}
}
}
int main(){
cin>>M>>N>>K>>D;//M houses; N gas ;K roads; D is the range 下标1 M+N
init();
for (int i = 0; i < K; ++i) {
int a1=get_one();
int a2=get_one();
int l;
cin>>l;
G[a1][a2]=l;
G[a2][a1]=l;
//cout<<a2<<a1<<endl;
}
//对所有gas进行dij
double all;
//all 每次的和 minloc 每次的最小值
//gas_all 全局的和 gas_min 全局的最小值
int choosegas=-1;
for (int i = M+1; i <=M+N ; ++i) {
minloc=INF;
all=0;
dij(i);
for (int j = 1; j <= M; ++j) {
if(d[j]<=D) {
//每次的和 每次的最小值
all += d[j];
if (d[j] < minloc) {
minloc = d[j];
}
}
else{
all=0;
minloc=INF;
break;
}
}
//cout<<"min&all:"<<minloc<<" "<<all<<endl;
if(minloc>gas_min){//最小值得最大值
gas_min=minloc;
gas_all=all;
choosegas=i;
// cout<<"gas:"<<choosegas<<endl;
}
else if(minloc==gas_min && all<gas_all){//all 尽量小
gas_all=all;
choosegas=i;
//cout<<"gas:"<<choosegas<<endl;
}
}
if(minloc!=INF){
cout<<"G"<<choosegas-M<<endl;
double out1=gas_min;
double out2=gas_all/M;
//cout<<"ouut"<<out2<<endl;
printf("%.1f %.1f
",out1,out2);
//cout<<choosegas<<" "<<gas_all<<" "<<gas_min;
}
else{
cout<<"No Solution"<<endl;
}
return 0;
}
AC代码:(我冲了)
#include<vector>
#include<iostream>
#include <algorithm>
#include <cmath>
#include<map>
#include <queue>
#include <stack>
#include<string.h>
using namespace std;
const int INF=1000000;
int G[1024][1024];
//直接把两个存在一起 1~1000 1001~1010
int M,N,K,D;
int d[1024];
double minloc;
int vis[1024];
double gas_all=INF;
double gas_min=-1;
void init(){
for (int i = 0; i <1024 ; ++i) {
for (int j = 0; j < 1024; ++j) {
G[i][j]=INF;
G[j][i]=INF;
}
}
}
void init_dij(){
for (int i = 0; i <= M+N; ++i) {
d[i]=INF;
vis[i]=0;
}
}
int get_one(){
int u=0;
string p;
cin>>p;//输入不能用char,可能会出现G11,199这样的数字
if(p[0]=='G'){
for(int j=1;j<p.length();j++){
u=u*10+p[j]-'0';
}
u+=M;
}else{
for(int j=0;j<p.length();j++){
u=u*10+p[j]-'0';
}
}
return u;
}
//d数组就是到每个点的距离了,其实这里都不需要存路径,,,用d直接说事就行了,反正d已经是最短路
void dij(int v){
init_dij();//d需要更新
d[v]=0;
for (int i = 1; i <= M+N; ++i) {
int u=-1,MIN=INF;
for (int j = 1; j <= M+N ; ++j) {
if(vis[j]==0 && d[j]<MIN){
u=j;
MIN=d[j];
}
}
if(u==-1) return ;
vis[u]=1;
for (int j = 1; j <= M+N ; ++j) {
if(vis[j]==0 && G[j][u]!=INF ){
if(d[j]>d[u]+G[j][u]){
d[j]=d[u]+G[j][u];
}
}
}
}
}
int main(){
cin>>M>>N>>K>>D;//M houses; N gas ;K roads; D is the range 下标1 M+N
init();
for (int i = 0; i < K; ++i) {
int a1=get_one();
int a2=get_one();
int l;
cin>>l;
G[a1][a2]=l;
G[a2][a1]=l;
//cout<<a2<<a1<<endl;
}
//对所有gas进行dij
double all;
//all 每次的和 minloc 每次的最小值
//gas_all 全局的和 gas_min 全局的最小值
int choosegas=-1;
for (int i = M+1; i <=M+N ; ++i) {
minloc=INF;
all=0;
dij(i);
for (int j = 1; j <= M; ++j) {
if(d[j]<=D) {
//每次的和 每次的最小值
all += d[j];
if (d[j] < minloc) {
minloc = d[j];
}
}
else{
all=0;
minloc=-1;
break;
}
}
if(minloc==-1){
continue;
}
//cout<<"min&all:"<<minloc<<" "<<all<<endl;
if(minloc>gas_min){//最小值得最大值
gas_min=minloc;
gas_all=all;
choosegas=i;
// cout<<"gas:"<<choosegas<<endl;
}
else if(minloc==gas_min && all<gas_all){//all 尽量小
gas_all=all;
choosegas=i;
//cout<<"gas:"<<choosegas<<endl;
}
}
if(minloc!=-1){
cout<<"G"<<choosegas-M<<endl;
double out1=gas_min;
double out2=gas_all/M;
//cout<<"ouut"<<out2<<endl;
printf("%.1f %.1f
",out1,out2);
//cout<<choosegas<<" "<<gas_all<<" "<<gas_min;
}
else{
cout<<"No Solution"<<endl;
}
return 0;
}
折腾这么久真不容易哇
喔,俺最近博客都写在csdn上咯
地址在这:
https://blog.csdn.net/weixin_49599247/article/details/119607570
欢迎访问喔