目录
1111 Online Map (30分) (升级版 dijkstra+dfs)
1131 Subway Map (30分) (dfs *)
方法2:
1139 First Contact (30分)
另一篇
#include
#include
#include
using namespace std;
const int inf = 999999999;
int dis[510], Time[510], e[510][510], w[510][510], dispre[510],Timepre[510], weight[510],NodeNum[510];
bool visit[510];
vector dispath, Timepath, temppath;
int st, fin, minnode = inf;
void dfsdispath(int v) {
dispath.push_back(v);
if(v == st) return ;
dfsdispath(dispre[v]);
}
void dfsTimepath(int v) {
Timepath.push_back(v);
if(v == st) return ;
dfsTimepath(Timepre[v]);
}
int main() {
fill(dis, dis + 510, inf);
fill(Time, Time + 510, inf);
fill(weight, weight + 510, inf);
fill(e[0], e[0] + 510 * 510, inf);
fill(w[0], w[0] + 510 * 510, inf);
int n, m;
scanf("%d %d", &n, &m);
int a, b, flag, len, t;
for(int i = 0; i < m; i++) {
scanf("%d %d %d %d %d", &a, &b, &flag, &len, &t);
e[a][b] = len;
w[a][b] = t;
if(flag != 1) {
e[b][a] = len;
w[b][a] = t;
}
}
scanf("%d %d", &st, &fin);
dis[st] = 0;
for(int i = 0; i < n; i++)
dispre[i] = i;
for(int i = 0; i < n; i++) {
int u = -1, minn = inf;
for(int j = 0; j < n; j++) {
if(visit[j] == false && dis[j] < minn) {
u = j;
minn = dis[j];
}
}
if(u == -1) break;
visit[u] = true;
for(int v = 0; v < n; v++) {
if(visit[v] == false && e[u][v] != inf) {
if(e[u][v] + dis[u] < dis[v]) {
dis[v] = e[u][v] + dis[u];
dispre[v] = u;
weight[v] = weight[u] + w[u][v];
} else if(e[u][v] + dis[u] == dis[v] && weight[v] > weight[u] + w[u][v]) {
weight[v] = weight[u] + w[u][v];
dispre[v] = u;
}
}
}
}
dfsdispath(fin);
Time[st] = 0;
fill(visit, visit + 510, false);
for(int i = 0; i < n; i++) {
int u = -1, minn = inf;
for(int j = 0; j < n; j++) {
if(visit[j] == false && minn > Time[j]) {
u = j;
minn = Time[j];
}
}
if(u == -1) break;
visit[u] = true;
for(int v = 0; v < n; v++) {
if(visit[v] == false && w[u][v] != inf) {
if(w[u][v] + Time[u] < Time[v]) {
Time[v] = w[u][v] + Time[u];
Timepre[v]= u;
NodeNum[v]=NodeNum[u]+1;
} else if(w[u][v] + Time[u] == Time[v]&&NodeNum[u]+1= 0; i--) {
printf("%d", dispath[i]);
if(i != 0) printf(" -> ");
}
printf("\nTime = %d: ", Time[fin]);
}
for(int i = Timepath.size() - 1; i >= 0; i--) {
printf("%d", Timepath[i]);
if(i != 0) printf(" -> ");
}
return 0;
}
1112 1133 1136 1137 1141
题目大意:找出一条路线,使得对任何给定的起点和终点,可以找出中途经停站最少的路线;如果经停站一样多,则取需要换乘线路次数最少的路线
分析: 一遍DFS即可~DFS过程中要维护两个变量:minCnt-中途经停的最少的站; minTransfer-需要换乘的最小次数~
0.可以这样计算出一条线路的换乘次数:用line[10000][10000]的数组 或者(unordered_map
1.可以这样计算出一条线路中途停站的次数:在dfs的时候有个变量cnt,表示当前路线是所需乘的第几个站,每次dfs时候将cnt+1表示向下遍历一层~cnt就是当前中途停站的次数~
2.可以这样输出结果:和计算线路换乘次数的思路一样,每当preLine和当前Line值不同的时候就输出一句话~保存preTransfer表示上一个换乘站,最后不要忘记输出preTransfer和最后一个站之间的路即使最后一个站并不是换乘站~
#include
#include
#include
using namespace std;
vector> v(10000);
int visit[10000], minCnt, minTransfer, start, end1;
unordered_map line;
vector path, tempPath;
int transferCnt(vector a) { //计算路径上的换乘站数
int cnt = -1, preLine = 0;
for (int i = 1; i < a.size(); i++) {
if (line[a[i-1]*10000+a[i]] != preLine) cnt++;
preLine = line[a[i-1]*10000+a[i]];
}
return cnt;
}
void dfs(int node, int cnt) {
if (node == end1 && (cnt < minCnt || (cnt == minCnt && transferCnt(tempPath) < minTransfer))) {
minCnt = cnt;
minTransfer = transferCnt(tempPath);
path = tempPath;
}
if (node == end1) return;
for (int i = 0; i < v[node].size(); i++) {
if (visit[v[node][i]] == 0) {
visit[v[node][i]] = 1;
tempPath.push_back(v[node][i]);
dfs(v[node][i], cnt + 1);
visit[v[node][i]] = 0;
tempPath.pop_back();
}
}
}
int main() {
int n, m, k, pre, temp;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &m, &pre);
for (int j = 1; j < m; j++) {
scanf("%d", &temp);
v[pre].push_back(temp);
v[temp].push_back(pre);
line[pre*10000+temp] = line[temp*10000+pre] = i + 1;
pre = temp;
}
}
scanf("%d", &k);
for (int i = 0; i < k; i++) {
scanf("%d%d", &start, &end1);
minCnt = 99999, minTransfer = 99999;
tempPath.clear();
tempPath.push_back(start);
visit[start] = 1;
dfs(start, 0);
visit[start] = 0;
printf("%d\n", minCnt);
int preLine = 0, preTransfer = start;
for (int j = 1; j < path.size(); j++) {
if (line[path[j-1]*10000+path[j]] != preLine) {
if (preLine != 0) printf("Take Line#%d from %04d to %04d.\n", preLine, preTransfer, path[j-1]);
preLine = line[path[j-1]*10000+path[j]];
preTransfer = path[j-1];
}
}
printf("Take Line#%d from %04d to %04d.\n", preLine, preTransfer, end1);
}
return 0;
}
方法2:
#include
#include
#include
using namespace std;
struct station{
int to, line;
}sta;
struct PATH{
int s ,e ,line;
}path;
vector< vector< station > > v(20000);
vector< struct PATH > ans,ans1;
int vis[10009] ,pres,prel ,minn=99999,mint=99999;
void dfs( int s , int e , int cnt , int takes ){
if( cnt > minn )
return ;
if( s == e ){
ans.push_back( path={ pres , s ,prel} );
if( cnt >n;
for( int i=1;i<=n;i++){
cin>>num>>t1;
for( int j=2;j<=num;j++){
cin>>t2;
v[t1].push_back( sta={t2,i} );
v[t2].push_back( sta={t1,i} );
t1=t2;
}
}
int k,s,e;
cin>>k;
for(int i=1;i<=k;i++){
cin>>s>>e;
pres = s;
prel = -1;
minn=99999,mint=99999;
fill(vis,vis+10009,0);
ans.clear();
ans1.clear();
vis[s] = 1;
dfs(s,e,0,0);
cout<
unordered_map
#include
#include
#include
#include
#include
#include
#include