当前位置: 代码迷 >> 综合 >> P1629 邮递员送信 最短路(一对多,多对一
  详细解决方案

P1629 邮递员送信 最短路(一对多,多对一

热度:42   发布时间:2023-12-06 11:19:55.0

题目:
在这里插入图片描述
思路:
这道题是一对多和多对一,一对多的问题笔记好解决,一对多的是第一次碰到。因为这道题里给的是有向图,所以不妨把所有的路反向存一遍,比如a->b存成b->a,然后就又变成了一对多问题。

#include<cstdio>
#include <iostream>
#include<cstring>
#include<algorithm>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
const int maxn=1111;
struct node
{
    int x,dis;bool operator >(const node &a)const{
    if(dis==a.dis) return x<a.x;return dis>a.dis;}
};
priority_queue <node,vector<node>,greater<node>> q,q1;
typedef pair<int,int> pii;
vector <pii> e[100*maxn],e1[100*maxn];
int n,m,s,day[maxn],dis[maxn];
bool vis[maxn];
int main()
{
    cin>>n>>m;for(int i=1;i<=m;i++){
    int x,y,w;cin>>x>>y>>w;if(x==y) continue;e[x].push_back({
    y,w});e1[y].push_back({
    x,w});}memset(dis,0x3f,sizeof(dis));dis[1]=0;q.push({
    1,0});while(!q.empty()){
    int temp=q.top().x;q.pop();if(vis[temp]) continue;vis[temp]=1; //cout<<"!!"<<temp<<endl;for(auto to:e[temp]){
    dis[to.first]=min(dis[to.first],dis[temp]+to.second);//cout<<"to.first="<<to.first<<" "<<"dis[to.first]"<<dis[to.first]<<endl;q.push({
    to.first,dis[to.first]});}}int ans=0;for(int i=1;i<=n;i++) ans+=dis[i];for(int i=1;i<=n;i++) vis[i]=0;memset(dis,0x3f,sizeof(dis));dis[1]=0;q1.push({
    1,0});//for(auto to:e1[1]) cout<<"to.first="<<to.first<<" "<<"dis[to.first]"<<dis[to.first]<<endl;while(!q1.empty()){
    int temp=q1.top().x;q1.pop();if(vis[temp]) continue;vis[temp]=1; //cout<<"!!"<<temp<<endl;for(auto to:e1[temp]){
    //cout<<"to.first="<<to.first<<" "<<"dis[to.first]"<<dis[to.first]<<endl;dis[to.first]=min(dis[to.first],dis[temp]+to.second);q1.push({
    to.first,dis[to.first]});}}for(int i=1;i<=n;i++) ans+=dis[i];cout<<ans<<endl;return 0;
}