http://acm.hdu.edu.cn/showproblem.php?pid=1535
水题
单向图,从1到P所有点,再从所有点回到1,问最小花费
先求一遍1的最短路,然后反向建图,再求一遍1的最短路
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <queue> using namespace std ; const int INF=0xfffffff ; struct node{ int s,t,v,nxt ; }e[1000005] ; int n,cnt,head[1000005],vis[1000005],dis[1000005] ; int rs[1000005],rt[1000005],rv[1000005] ; void add(int s,int t,int v) { e[cnt].s=s ; e[cnt].t=t ; e[cnt].v=v ; e[cnt].nxt=head[s] ; head[s]=cnt++ ; } void spfa(int s) { for(int i=1 ;i<=n ;i++) dis[i]=INF ; dis[s]=0 ; memset(vis,0,sizeof(vis)) ; vis[s]=1 ; queue <int> q ; q.push(s) ; while(!q.empty()) { int u=q.front() ; q.pop() ; vis[u]=0 ; for(int i=head[u] ;i!=-1 ;i=e[i].nxt) { int tt=e[i].t ; if(dis[tt]>dis[u]+e[i].v) { dis[tt]=dis[u]+e[i].v ; if(!vis[tt]) { vis[tt]=1 ; q.push(tt) ; } } } } } int main() { int t ; scanf("%d",&t) ; while(t--) { cnt=0 ; memset(head,-1,sizeof(head)) ; int q ; scanf("%d%d",&n,&q) ; for(int i=0 ;i<q ;i++) { scanf("%d%d%d",&rs[i],&rt[i],&rv[i]) ; add(rs[i],rt[i],rv[i]) ; } int ans=0 ; spfa(1) ; for(int i=1 ;i<=n ;i++) ans+=dis[i] ; cnt=0 ; memset(head,-1,sizeof(head)) ; for(int i=0 ;i<q ;i++) add(rt[i],rs[i],rv[i]) ; spfa(1) ; for(int i=1 ;i<=n ;i++) ans+=dis[i] ; printf("%d\n",ans) ; } return 0 ; }