一、问题描述
试题编号: | 201712-4 |
试题名称: | 行车路线 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航。 输入格式 输入的第一行包含两个整数n, m,分别表示路口的数量和道路的数量。路口由1至n编号,小明需要开车从1号路口到n号路口。 输出格式 输出一个整数,表示最优路线下小明的疲劳度。 样例输入 6 7 样例输出 76 样例说明 从1走小道到2,再走小道到3,疲劳度为52=25;然后从3走大道经过4到达5,疲劳度为20+30=50;最后从5走小道到6,疲劳度为1。总共为76。 数据规模和约定 对于30%的评测用例,1 ≤ n ≤ 8,1 ≤ m ≤ 10; |
二、分析解答
说一说吧,其实一开始我就做对了,不过时间复杂度比较高,然后就瞎改,80分是因为我的那个算长度是一个函数特别复杂,然后好像是递归的,反正很慢。中间错了一堆是因为,我想把三个版本的函数几乎两两结合看看是哪里错了,然后就发现了一些我也不清楚的东西,总之乱改一通,其实都什么都没用。
没办法这题我干不动。只有90分,剩下的应该是超时,不会nlogn的代码。这是版本三。看着办吧,我好差劲一点也不会。
#include <iostream>
#include <climits>
#include <queue>
using namespace std;
#define INF LONG_LONG_MAX
#define MAX_NODE 505
#define BG 0
#define SM 1
#define NONE 2
///node,edge
int n_node,m_edge;
///edge
int t_type,a_start,b_end;
long long c_len;
///road
long long len[MAX_NODE][MAX_NODE];
int type[MAX_NODE][MAX_NODE];
int path[MAX_NODE];
long long tired[MAX_NODE];
long long before_sm[MAX_NODE];
long long last_sm[MAX_NODE];
void init_path_dist(int i){
if(type[0][i]!=NONE){
path[i]=0;
tired[i]=(type[0][i] == BG ? len[0][i] : len[0][i]*len[0][i]);
before_sm[i]=(type[0][i] == BG ? len[0][i] : 0);
last_sm[i]=(type[0][i] == BG ? 0 : len[0][i]);
}else{
path[i]=-1;tired[i]=INF;
}
}
long long dij(){
priority_queue<node> que;
///put 0 in the the set
int i,j;
int flag[n_node]={};
for(i=0;i<n_node;i++){
init_path_dist(i);
}
flag[0]=1;
///put n-1 node in the set
for(i=0;i<n_node-1;i++){
///explore: find mindist node from not in and make it in.
long long mindist=INF,minindex=-1;
for(j=0;j<n_node;j++){
if(flag[j]==0&&tired[j]<mindist){
minindex=j;mindist=tired[j];
}
}
if(mindist>=INF)break;
flag[minindex]=1;
///exploit:will the node reduce the dist?
for(j=0;j<n_node;j++){
if(flag[j]==0&&type[minindex][j]!=NONE){
long long newdist=INF,t_last_sm=0,t_before=before_sm[minindex];
if(type[minindex][j]==BG){
newdist=tired[minindex]+len[minindex][j];
t_before=newdist;
}else if(type[minindex][j]==SM){
newdist=before_sm[minindex]+(last_sm[minindex]+len[minindex][j])*(last_sm[minindex]+len[minindex][j]);
t_last_sm=last_sm[minindex]+len[minindex][j];
}
///cout<<minindex+1<<" "<<j+1<<" "<<" before:"<<before_sm[minindex]<<" last:"<<last_sm[j]<<" len:"<<len[minindex][j]<<" "<<newdist<<" "<<tired[j]<<endl;
if(newdist<tired[j]){
path[j]=minindex;
tired[j]=newdist;
before_sm[j]=t_before;
last_sm[j]=t_last_sm;
}
}
}
//for(j=0;j<n_node;j++){
//cout<<path[j]<<" ";
//}cout<<endl;
}
return tired[n_node-1];
}
int main()
{
///input
cin>>n_node>>m_edge;
///init
int i,j;
for(i=0;i<n_node;i++){
for(j=0;j<n_node;j++){
if(i==j){len[i][j]=0;type[i][j]=BG;}
else{len[i][j]=INF;type[i][j]=NONE;}
}
}
///input
for(i=0;i<m_edge;i++){
cin>>t_type>>a_start>>b_end>>c_len;a_start--;b_end--;
len[a_start][b_end]=len[b_end][a_start]=c_len;
type[a_start][b_end]=type[b_end][a_start]=t_type;
}
cout << dij();
return 0;
}
这也是我的90分代码,版本二。
#include <cstdio>
#include <iostream>
#include <climits>
using namespace std;
#define INF LONG_LONG_MAX
#define BG 0
#define SM 1
#define NONE 2
#define MAX_NODE 505
#define MAX_EDGE 100005
///node,edge
int n_node,m_edge;
///edge
int t_type,a_start,b_end;
long long c_len;
///road
typedef struct ROAD{
long long len[MAX_NODE][MAX_NODE];
int type[MAX_NODE][MAX_NODE];
int path[MAX_NODE];
long long tir[MAX_NODE];
long long l_sm[MAX_NODE];
}Road;
Road road;
///end!=0
long long dist(int end){
///not connect
if(road.path[end]==-1){
return INF;
}
int i,j;
int last_type=NONE;
long long sum=0,tmp=0;
for(i=end;i!=0;i=j){
j=road.path[i];
if(last_type==NONE){
tmp=road.len[j][i];
last_type=road.type[j][i];
continue;
}
if(road.type[j][i]!=last_type){
if(last_type==BG){
sum+=tmp;
}else if(last_type==SM){
sum+=(tmp*tmp);
}
last_type=road.type[j][i];
tmp=road.len[j][i];
}else{
last_type=road.type[j][i];
tmp+=road.len[j][i];
}
}
if(last_type==BG){
sum+=tmp;
}else if(last_type==SM){
sum+=(tmp*tmp);
}
return sum;
}
///mid!=0
long long dist_mid(int mid,int next){
long long lenn=0;
int tmp=road.path[next];
road.path[next]=mid;
lenn=dist(next);
road.path[next]=tmp;
return lenn;
}
///0->n-1
long long dij(){
///init
int i,j;
for(i=0;i<n_node;i++){
if(road.len[0][i]<INF){
road.path[i]=0;
}else{
road.path[i]=-1;
}
}
///put in n node
int flag[n_node]={};
flag[0]=1;
for(i=0;i<n_node-1;i++){
///find mindist from not in and make it in.explore!
long long mindist=INF,minindex=-1;
for(j=0;j<n_node;j++){
if(flag[j]==0&&dist(j)<mindist){
minindex=j;mindist=dist(j);
}
}
if(mindist>=INF)break;
flag[minindex]=1;
///is there some change?exploit!
for(j=0;j<n_node;j++){
if(flag[j]==0&&road.len[minindex][j]!=INF&&dist_mid(minindex,j)<dist(j)){
road.path[j]=minindex;
}
}
}
return dist(n_node-1);
}
int main(){
///input
cin>>n_node>>m_edge;
///init
int i,j;
for(i=0;i<n_node;i++){
for(j=0;j<n_node;j++){
if(i==j){
road.len[i][j]=0;
road.type[i][j]=NONE;
}else{
road.len[i][j]=INF;
road.type[i][j]=NONE;
}
}
}
///input
for(i=0;i<m_edge;i++){
cin>>t_type>>a_start>>b_end>>c_len;
a_start--;b_end--;
road.len[a_start][b_end]=road.len[b_end][a_start]=c_len;
road.type[a_start][b_end]=road.type[b_end][a_start]=t_type;
}
long long tired = dij();
cout << tired;
return 0;
}
还有这个,是版本一,也是90分。
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define BG 0
#define SM 1
#define MAX_NODE 505
#define MAX_EDGE 100000
///node,edge,
int n_node,m_edge;
///edge
long long t_type,a_start,b_end,c_len;
///road
typedef struct ROAD{
long long len[MAX_NODE][MAX_NODE];
int type[MAX_NODE][MAX_NODE];
int path[MAX_NODE];
}Road;
Road road;
long long dist(int end){
if(road.path[end]==-1){
return INF;
}
int i,j;
int last_type=-1;
long long sum=0,tmp=0;
for(i=end;i!=0;i=j){
j=road.path[i];
if(road.type[j][i]!=last_type){
if(last_type==BG){
sum+=tmp;
}else if(last_type==SM){
sum+=(tmp*tmp);
}else{
tmp=road.len[j][i];
last_type=road.type[j][i];
continue;
}
tmp=0;
}
last_type=road.type[j][i];
tmp+=road.len[j][i];
}
if(last_type==BG){
sum+=tmp;
}else if(last_type==SM){
sum+=(tmp*tmp);
}
//cout<<sum;
return sum;
}
long long dist_mid(int mid,int next){
if(road.len[mid][next]==INF){
return INF;
}
int x=road.path[mid];
long long lenn=0;
if(road.type[mid][next]==road.type[x][mid]){
int m=road.path[next];
road.path[next]=mid;
lenn=dist(next);
road.path[next]=m;
}else{
lenn=dist(mid)+road.len[mid][next];
}
return lenn;
}
///0->n-1
long long dij(){
int i,j;
for(i=0;i<n_node;i++){
if(road.len[0][i]<INF)
road.path[i]=0;
else
road.path[i]=-1;
}
///put in n node
int flag[n_node]={};
flag[0]=1;
for(i=0;i<n_node-1;i++){
///find mindist from not in and make it in.explore!
long long mindist=INF,minindex=-1;
for(j=0;j<n_node;j++){
if(flag[j]==0&&dist(j)<mindist){
minindex=j;mindist=dist(j);
}
}
///cout<<minindex<<" "<<mindist<<endl;
flag[minindex]=1;
///is there some change?exploit!
for(j=0;j<n_node;j++){
if(mindist!=INF&&flag[j]==0&&dist_mid(minindex,j)<dist(j)){
road.path[j]=minindex;
}
}
}
// for(i=0;i<n_node;i++){
// cout<<road.path[i]<<" "<<dist(i)<<endl;
// }
return dist(n_node-1);
}
int main(){
///input
cin>>n_node>>m_edge;
int i,j;
for(i=0;i<n_node;i++){
for(j=0;j<n_node;j++){
if(i==j){
road.len[i][j]=0;
road.type[i][j]=0;
}else{
road.len[i][j]=INF;
road.type[i][j]=-2;
}
}
}
for(i=0;i<m_edge;i++){
cin>>t_type>>a_start>>b_end>>c_len;a_start--;b_end--;
road.len[a_start][b_end]=road.len[b_end][a_start]=c_len;
road.type[a_start][b_end]=road.type[b_end][a_start]=t_type;
}
long long tired = dij();
cout << tired;
return 0;
}