蒟蒻求教,60分,做法与大佬们都不一样,求调or思路上的hack
查看原帖
蒟蒻求教,60分,做法与大佬们都不一样,求调or思路上的hack
901562
ysq20110325楼主2023/7/28 19:47
#include<bits/stdc++.h>
using namespace std;
int n,m,dis[1111111],head[1111111],tot;
bool vis[1111111];
vector<int> v[1111111];//存储最短路径都经过了哪些边 
struct Edge{
    int next;
    int to;
    int w;
}edge[1111111];
void add(int x,int y,int w){//链式前向星存图 
    tot++;
    edge[tot].to=y;
    edge[tot].w=w;
    edge[tot].next=head[x];
    head[x]=tot;
    return;
}
priority_queue<pair<int,int> > q;
//优先队列优化dijskra 
set<int> s;
//选用set存储每一条能到达n点的路径长度,set同时能兼顾去重与排序的功能,最后答案就是其中的第二个元素 
void dijskra(){
    while(q.size()){
        int x=q.top().second;
        q.pop();
        if(vis[x]!=0)continue;
        else vis[x]=1;
        for(int i=head[x];i;i=edge[i].next){
            int y=edge[i].to;
            int w=edge[i].w;
            if(y==n){
                s.insert(dis[x]+w);//存储一下当前路径到达n点的长度 
            }
            if(dis[x]+w<dis[y]){
                dis[y]=dis[x]+w;
                q.push(make_pair(-dis[y],y));
                v[y]=v[x];//存一下(在当前的最短路径中)经过了哪些边才到达该点 ;
                v[y].push_back(i);
            }
        }
    }
    return;
}
int main(){
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
    }
    memset(dis,0x3f,sizeof dis);
    dis[1]=0;
    q.push(make_pair(0,1));
    dijskra();
    for(int i=0;i<v[n].size();i++){
    	s.insert(dis[n]+edge[v[n][i]].w*2);//可能要走重复的路,但重复的边一定只有一条,且一定被包含于最短路中 
//    	cout<<edge[v[n][i]].w<<endl;
	}
    auto it=s.begin();
    it++;
    cout<<*it;//输出set中的元素似乎只能用指针 
    return 0;
}
//hack
//5 10
//1 2 1982
//2 3 3963
//3 4 2046
//3 5 1353
//4 2 1370
//4 1 2192
//5 3 2898
//4 3 1395
//4 1 3722
//3 2 4596
//正确答案为5591 实测为6485(疑似在判重边时出错) 
2023/7/28 19:47
加载中...