您的位置:首页 > 其它

PAT 1018的陷阱

2013-11-13 21:06 274 查看
这道题目要把所有最短路径先找到并且保存好,然后再遍历找最优的。如果一边找最短路径一遍贪心,可能会导致整体表现比较好的路线在前面被扔掉。

第二要注意题目的理解,从PBMC出发,到终点,路上把每个站点都调整到最优。路上如果后面有站点可以获得到多余的车,也不能把车带回来给前面的站点。从PBMC带出来的车一定要保证每时每刻都够用。

针对这些坑设计了一些测试数据,把数据和我AC的程序都贴出来。

#include<stdio.h>
#include<vector>
#include<algorithm>
#include<set>

#define MY_INT_MAX 1000000000

using namespace std;

#undef DEBUG
int n,cmax,sp,m;
int map[501][501];
int bike[501];
bool inS[501];
vector<vector<int>> all_paths[501];
int length[501];

int main()
{
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);

//input
scanf("%d%d%d%d",&cmax,&n,&sp,&m);
int i,j,from,to,time;
for(i=1;i<=n;i++)
scanf("%d",&bike[i]);
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
map[i][j]=MY_INT_MAX;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&from,&to,&time);
map[from][to]=time;
map[to][from]=time;
}

//shortest path
for(i=1;i<=n;i++)
{
inS[i]=false;
length[i]=map[0][i];
if(length[i]<MY_INT_MAX)
{
vector<int> v;
v.push_back(i);
vector<vector<int>> vv;
vv.push_back(v);
all_paths[i]=vv;
}
}
inS[0]=true;

int min;
int minV;
while(!inS[sp])
{
minV=MY_INT_MAX;
for(i=1;i<=n;i++)
{
if(!inS[i] && length[i]<minV)
{
min=i;
minV=length[i];
}
}

#ifdef DEBUG
int debug_i;
for(debug_i=1;debug_i<=n;debug_i++)
{
printf("length[%d]=%d ",debug_i,length[debug_i]);
}
printf("\nin this iteration, min=%d, length[min]=%d\n",min,length[min]);
#endif
inS[min]=true;
for(i=1;i<=n;i++)
{
if(inS[i])
continue;
#ifdef DEBUG
printf("now i=%d, length[i]=%d\n",i,length[i]);
#endif
if(length[i]>map[min][i]+length[min])
{
#ifdef DEBUG
printf("find a new short path to %d\n",i);
#endif
length[i]=map[min][i]+length[min];
all_paths[i].clear();
for(vector<vector<int>>::iterator it=all_paths[min].begin();it!=all_paths[min].end();it++)
{
vector<int> nv= *it;
nv.push_back(i);
all_paths[i].push_back(nv);
}
}
else if(length[i]==map[min][i]+length[min])
{
#ifdef DEBUG
printf("find an equal path to %d\n",i);
#endif
for(vector<vector<int>>::iterator it=all_paths[min].begin();it!=all_paths[min].end();it++)
{
vector<int> nv= *it;
nv.push_back(i);
all_paths[i].push_back(nv);
}
}
}
}

int minSend=99999999;
int send;
int record_send;
vector<vector<int>> possible_paths;

//find the paths with less send
for(vector<vector<int>>::iterator it=all
4000
_paths[sp].begin();it!=all_paths[min].end();it++)
{
send=0;
record_send=0;
for(vector<int>::iterator jt=it->begin();jt!=it->end();jt++)
{
send+=cmax/2-bike[*jt];
if(send>record_send)
record_send=send;
}
#ifdef DEBUG
printf("record_send=%d, minSend=%d\n",record_send,minSend);
#endif
if(record_send<minSend)
{
minSend=record_send;
possible_paths.clear();
possible_paths.push_back(*it);
}
else if(record_send == minSend)
{
possible_paths.push_back(*it);
}
}

int store;
int minStore=99999999;
vector<vector<int>>::iterator bestPath;
for(vector<vector<int>>::iterator it=possible_paths.begin();it!=possible_paths.end();it++)
{
store=minSend;
for(vector<int>::iterator jt=it->begin();jt!=it->end();jt++)
{
store=store-(cmax/2-bike[*jt]);
}
#ifdef DEBUG
printf("this path, store=%d\n",store);
#endif
if(store<minStore)
{
minStore=store;
bestPath=it;
}
}
printf("%d 0",minSend);
for(vector<int>::iterator jt=bestPath->begin();jt!=bestPath->end();jt++)
printf("->%d",*jt);
printf(" %d",minStore);

return 0;
}测试数据:
10 9 3 12
1 1 1 1 1 9 9 8 9
0 1 1
1 2 1
2 3 1
0 4 2
4 5 1
5 3 1
0 6 1
6 7 1
7 3 1
0 8 1
8 9 1
9 3 1
16 4 4 6
16 2 1 0
0 1 2
1 4 2
0 2 1
2 4 1
0 3 1
3 4 1

10 7 6 8
0 0 10 10 10 0 9
0 1 1
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
0 7 5
7 6 1


10 5 5 6
10 10 9 9 10
0 1 1
1 2 1
2 5 1
0 3 1
3 4 1
4 5 1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PAT