题目:
思路:
这道题是一对多和多对一,一对多的问题笔记好解决,一对多的是第一次碰到。因为这道题里给的是有向图,所以不妨把所有的路反向存一遍,比如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;
}