社区讨论
两次dijkstra+pre(vector数组)记录最短路+找最长重合
P2149[SDOI2009] Elaxia的路线参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mi7e0yi3
- 此快照首次捕获于
- 2025/11/20 20:08 4 个月前
- 此快照最后确认于
- 2025/11/20 20:08 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define res register int
const int maxn=1505;
vector<int> v[maxn],pre[2][maxn];
//v是邻接矩阵 pre[1]是第一个人从实验室到宿舍的最短路上的记录,记录每一个最短路上的点前一个节点。因为可能有多个,所以用的是vector
//pre[2]表示的就是第二个人实验室到宿舍最短路的记录
int N,M,b1,e1,b2,e2,dis[maxn][maxn];//dis是邻接矩阵,方便直接获取两个点之间的距离
int flag[maxn];
int Max=0;
struct Node{
int num,sum;
};
bool operator<(const Node a,const Node b){
return b.sum>a.sum;
}
void dijkstra(int s,int cnt)
{
int len[maxn],vis[maxn];
memset(len,inf,sizeof(int)*(N+2));
memset(vis,0,sizeof(int)*(N+2));
len[s]=0;
priority_queue<Node> q;
q.push((Node){s,0});
int size;
while(!q.empty()){
Node now=q.top();
q.pop();
if(vis[now.num]) continue;
vis[now.num]=1;
int size=v[now.num].size();
for(res i=0;i<size;i++){
int y=v[now.num][i];
if(len[y]>len[now.num]+dis[now.num][y]){
len[y]=len[now.num]+dis[now.num][y];
pre[cnt][y].clear();
pre[cnt][y].push_back(now.num);
if(!vis[y]) q.push((Node){y,len[y]});
}else if(len[y]==len[now.num]+dis[now.num][y]){
pre[cnt][y].push_back(now.num);
}
}
}
}
void dfs1(int x){//对第一个实验室和宿舍,从终点开始dfs,玲所有最短路上的点i,都有flag【i】 =1
if(b1==x){
flag[x]=1;
return;
}else{
flag[x]=1;
for(res i=0;i<pre[0][x].size();i++){
int fa=pre[0][x][i];
dfs1(fa);
}
}
}
void dfs2(int x,int sum){//对二个实验室和宿舍反着利用pre[1]进行遍历
//如果flag[x]==flag[fa] && flag[fa]==1 说明当前路是第一个宿舍到实验室之间的最短路,就把这个边加到sum上
//最后我们比较取sum较大的
if(b2==x){
Max=max(Max,sum);
return;
}else{
int size=pre[1][x].size();
for(res i=0;i<pre[1][x].size();i++){
int fa=pre[1][x][i];
if(1==flag[x]&&1==flag[fa])
sum+=dis[x][fa];
dfs2(fa,sum);
if(1==flag[x]&&1==flag[fa])
sum-=dis[x][fa];
}
}
}
int main()
{
cin>>N>>M;
cin>>b1>>e1>>b2>>e2;
int from,to,val;
for(res i=0;i<M;i++){
scanf("%d%d%d",&from,&to,&val);
v[from].push_back(to);
v[to].push_back(from);
dis[from][to]=dis[to][from]=val;
}
dijkstra(b1,0);
dijkstra(b2,1);
// for(res i=1;i<=N;i++){
// for(res j=0;j<pre[0][i].size();j++){
// printf("%d ",pre[0][i][j]);
// }
// printf("\n");
// }
dfs1(e1);
dfs2(e2,0);
printf("%d",Max);
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...