poj 1511 正向 反向 构两个图

有向图 源点为1 求源点到其他各点的最短距离之和 再在其他点到源点的最短距离之和 再加起来 多源点一终点 只要反向构图就行了

Sample Input

2 //T
2 2 //结点数 边数
1 2 13 //u v w
2 1 33
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50
Sample Output

46
210

堆优化:  跑了6S...

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <cstring>
  4 # include <algorithm>
  5 # include <cmath>
  6 # include <queue>
  7 # define LL long long
  8 using namespace std ;
  9
 10 const int INF=0x3f3f3f3f;
 11 const int MAXN=1000010;
 12 struct qnode
 13 {
 14     int v;
 15     int c;
 16     qnode(int _v=0,int _c=0):v(_v),c(_c){}
 17     bool operator <(const qnode &r)const
 18     {
 19         return c>r.c;
 20     }
 21 };
 22 struct Edge
 23 {
 24     int v,cost;
 25     Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
 26 };
 27 vector<Edge>E[MAXN];
 28 bool vis[MAXN];
 29 int dist[MAXN];
 30 int u[MAXN] , v[MAXN] , w[MAXN] ;
 31 int n ;
 32 void Dijkstra(int start)//点的编号从1开始
 33 {
 34     memset(vis,false,sizeof(vis));
 35     for(int i=1;i<=n;i++)dist[i]=INF;
 36     priority_queue<qnode>que;
 37     while(!que.empty())que.pop();
 38     dist[start]=0;
 39     que.push(qnode(start,0));
 40     qnode tmp;
 41     while(!que.empty())
 42     {
 43         tmp=que.top();
 44         que.pop();
 45         int u=tmp.v;
 46         if(vis[u])continue;
 47         vis[u]=true;
 48         for(int i=0;i<E[u].size();i++)
 49         {
 50             int v=E[tmp.v][i].v;
 51             int cost=E[u][i].cost;
 52             if(!vis[v]&&dist[v]>dist[u]+cost)
 53             {
 54                 dist[v]=dist[u]+cost;
 55                 que.push(qnode(v,dist[v]));
 56             }
 57         }
 58     }
 59 }
 60 void addedge(int u,int v,int w)
 61 {
 62     E[u].push_back(Edge(v,w));
 63 }
 64
 65 int main ()
 66 {
 67    // freopen("in.txt","r",stdin) ;
 68     int m ;
 69     int T ;
 70     scanf("%d" , &T) ;
 71     while (T--)
 72     {
 73         scanf("%d %d" , &n , &m) ;
 74         LL ans = 0 ;
 75         int i , j ;
 76         for(i=1;i<=m;i++)
 77             scanf("%d%d%d" , &u[i] , &v[i] , &w[i]) ;
 78
 79         for(i=1;i<=n;i++)
 80             E[i].clear();
 81         for(i=1;i<=m;i++)
 82             addedge(u[i],v[i],w[i]) ;
 83         Dijkstra(1) ;
 84         for(i=1;i<=n;i++)
 85             ans += dist[i] ;
 86
 87         for(i=1;i<=n;i++)
 88             E[i].clear();
 89         for(i=1;i<=m;i++)
 90             addedge(v[i],u[i],w[i]) ;
 91         Dijkstra(1) ;
 92         for(i=1;i<=n;i++)
 93             ans += dist[i] ;
 94
 95         cout<<ans<<endl ;
 96
 97     }
 98
 99     return 0 ;
100 }

时间: 2024-10-14 10:15:03

poj 1511 正向 反向 构两个图的相关文章

DIjkstra(反向边) POJ 3268 Silver Cow Party || POJ 1511 Invitation Cards

题目传送门 1 2 题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程 分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路. POJ 3268 //#include <bits/stdc++.h> #include <cstdio> #include <queue> #include <algorithm> #include <cstring> using namespace

POJ 1511 Invitation Cards (最短路)

Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 19215   Accepted: 6311 Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They wan

poj 1511 Dijkstra的另一种用法---求其他点到源点的最短路

传送门:http://poj.org/problem?id=1511 题目其实到现在我都没读懂,到底是哪里看出来的,ans是源点到各个点最短路的和外加各个点到源点的最短路的和,不过重要的是学到dijkstra的另一种用法--求各个点到源点的距离,原理不难理解,就是把dijkstra求单源最短路径的过程逆过来: 1.取源点加入S集合,设其余点在T集合 2.找到达源点的最小边,将该边连的点加入S,更新T到S的各个点的最短路径,取最短的边,继续2的过程 而dijastra求单源最短路径的过程 1.取源

[2016-04-05][POJ][1511][Invitation Cards]

时间:2016-04-05 12:57:22 星期二 题目编号:[2016-04-05][POJ][1511][Invitation Cards] 题目大意:给定一个有向图,从点1出发,分别到各个站点后,又回到点1,问最少需要多少车费, 分析: 从1跑一次最短路,然后矩阵转置,再跑一次最短路,两次求和 这里不能用邻接矩阵保存,所以改成邻接表,然后矩阵转置的操作变成重新加一次边 遇到的问题:用vector存图超时,改用数组实现 #include <queue> #include <algo

POJ 1511 Invitation Cards

题目来源:http://poj.org/problem?id=1511 题目很长,花了不少时间才理解题意,目的就是为了求出来回两次最小路径(即为本题的差旅费)之和, 第一次从CCS(1)出发到各个点路径最小,SPFA算法没得说,回来时终点是确定的都是CCS(1),相当于把路 径反过来,即把有向图去反方向,又是从1出发到各个点路径最小,再用一个SPFA.注意ans要用long long 不然也WA,这个地方WA了好几次,虽然更改后AC了,但还是不明白,题目明明写了smaller than 1000

HDU 1535 Invitation Cards (POJ 1511)

两次SPFA.求 来 和 回 的最短路之和. 用Dijkstra+邻接矩阵确实好写+方便交换,但是这个有1000000个点,矩阵开不了. d1[]为 1~N 的最短路. 将所有边的 邻点 交换. d2[] 为 1~N 的最短路. 所有相加为 所要答案. 忧伤的是用SPFA  "HDU 1535"  AC了,但是POJ 一样的题 "POJ 1511" 就WA了. 然后强迫症犯了,不停的去测试. 题意中找到一句关键话 :Prices are positive integ

linux系统建立DNS主从域名服务器实现正向反向查询

实验要求:建立DNS主从域名服务器实现正向反向查询 实验步骤: 1.正向查询 首先挂载并且安装bind软件 查看工作目录 进入主配置文件并且修改配置文件的监听端口的ip地址指向自己,允许查询的网段为任何人 区域文件 进入并配置区域设置文件 在进入named 查看,并且将区域配置的数据文件named.localhost文件的内容拷贝到benet.com.zone当中并重新编辑 建立正向查询 指定本机地址为DNS服务器地址写入etc/resolv.conf文件,写入完之后查看下 关闭防火墙,并且开启

POJ 3281 Dining(最大流建图 &amp;&amp; ISAP &amp;&amp; 拆点)

题目链接:http://poj.org/problem?id=3281 努力练建图ing!!! 题意:有 N 头牛,有 F 种食物和 D 种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料. 第2行-第N+1行.是牛i 喜欢A种食物,B种饮料,及食物种类列表和饮料种类列表. 问最多能使几头牛同时享用到自己喜欢的食物和饮料.->最大流. 本题难点是建图: 思路:一般都是左边一个集合表示源点与供应相连,右边一个集合表示需求与汇点相连. 但是本题,牛作为需求仍然是一个群体,但是供

Linux之DNS正向反向解析以及主从复制、子域授权、转发和view功能

关于DNS服务器我想大家并不陌生,通常情况下我们都只知道DNS服务器是域名解析用的,如果我们没有DNS服务器那么我们想要访问互联网上的网站什么的就不得不去记忆这些网站的IP地址了.对于我们而言众多的IP地址是很难记忆的而且也不方便.所以就出现过了DNS服务器.主要实现把主机名解析成IP地址,这样就方便我们在网上通信. 通常情况下我们之用到了DNS服务器的正向解析功能,而DNS还有方向解析功能,就是把IP地址解析成主机名的. 那么接下来就来跟大家分享一下DNS的工作方式. DNS是基于C/S架构的