题意很简单,有一个无向图,有2类节点,起点属于I类点,终点属于II类点,求从起点到终点的一条最短路,使得路径最多仅仅有1条边是连接I类点和II类点的。
我的做法是对于I类点和II类点分别求相对于起点和终点的单源最短路径,然后枚举连接I类点和II类点的边,求得最短路径。
但是似乎有更好的方法,就是同类点间的边作双向边处理,而连接I类点与II类点的边作单向边处理,这样只要求得一次最短路,不用枚举了


1
# include <iostream>
2
# include <cstdio>
3
# include <cstring>
4
using namespace std;
5
const int N=800;
6
const int M=30000;
7
int map[N][N],dis[N];
8
bool camp[N],used[N];
9
10
void dij(int n,int start)
11

{
12
memset(used,0,sizeof(used));
13
dis[start]=0;
14
while(true)
15
{
16
int minnum=0xfffffff,pos=-1;
17
for(int i=1;i<=n;i++)
18
if(!used[i]&&dis[i]!=-1&&dis[i]<minnum)
19
minnum=dis[i],pos=i;
20
if(pos==-1) break;
21
used[pos]=1;
22
for(int i=1;i<=n;i++)
23
if(!used[i]&&map[pos][i]!=-1&&camp[pos]==camp[i]&&(dis[i]==-1||dis[i]>dis[pos]+map[pos][i]))
24
dis[i]=dis[pos]+map[pos][i];
25
}
26
}
27
int main()
28

{
29
while(true)
30
{
31
int n,m;
32
scanf("%d",&n);
33
if(!n) break;
34
scanf("%d",&m);
35
memset(map,-1,sizeof(map));
36
while(m--)
37
{
38
int s,e,len;
39
scanf("%d%d%d",&s,&e,&len);
40
if(map[s][e]==-1||map[s][e]>len)
41
{
42
map[s][e]=map[e][s]=len;
43
}
44
}
45
for(int i=1;i<=n;i++)
46
{
47
int t;
48
scanf("%d",&t);
49
switch(t)
50
{
51
case 1:camp[i]=0;break;
52
case 2:camp[i]=1;break;
53
};
54
}
55
memset(dis,-1,sizeof(dis));
56
dij(n,1);
57
dij(n,2);
58
int minroad=0xfffffff;
59
for(int i=1;i<=n;i++)
60
for(int j=1;j<=n;j++)
61
if(camp[i]==camp[1]&&camp[j]==camp[2]&&map[i][j]!=-1&&dis[i]!=-1&&dis[j]!=-1&&dis[i]+dis[j]+map[i][j]<minroad)
62
minroad=dis[i]+dis[j]+map[i][j];
63
if(minroad==0xfffffff)
64
printf("-1\n");
65
else
66
printf("%d\n",minroad);
67
}
68
return 0;
69
}
70