表4-2-1 例4.2.1样例
输入格式:第一行输入三个整数 , 和 ;以下 行,每行三个整数 , , ,表示 和 之间有
一条权值为 的点。
输出格式:第一行输出一个整数 ,表示剩余的边的条数 ( );第二行输出 条边的编号,编
号按照输入顺序从 到 。
数据范围: ,
问题剖析:该题是对迪杰斯特拉算法求解过程的灵活运用,算法求解最短路时,一旦一个点得到扩展,
那么源点到该点的最短路就已经确定,这样,从源点出发的所有最短路构成的图一定是一棵树,这样最
多剩余 条即为最多保留 个结点,这些结点构成了一棵以 号为根的最短路树。我们只要在迪杰
斯特拉求解最短路的过程中保留包括源点在内的前 个点,并输出对应的边,或者在跑完最短路后
在最短路树上进行搜索(BFS或DFS均可)即可,下面以广搜为例给出核心代码:
dijkstra(1); // 通过单源最短路得到源点到每个点的最短距离
if(n<k+1) cout<<n-1<<endl; // 边数的上限为n-1
else cout<<k<<endl;
queue<ll> lst;
memset(vis,0,sizeof(vis));
lst.push(1);
vis[1]=1;
ans=0;
while(lst.size()&&ans<k)
{
ll u=lst.front();lst.pop();
for(int i=head[u];i;i=e[i].nxt)
{
ll v=e[i].v,w=e[i].w;
if(!vis[v]&&dis[v]==dis[u]+w) // 当前边是最短路书上的边
{
ans++;
cout<<(i+1)/2<<" "; // 无向图每条边正反各存一次
if(ans==k) break;
lst.push(v);
vis[v]=1;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
评论0