hdu 1535 Invitation Cards

点击打开链接hdu1535

思路:最短路+SPFA

分析:
1 题目要求的是总的最小的花费,意思就是要求每一个人的花费都最小。
2 由于每一个人都是从1出去,最后还是都要回到1的,那么求解的时候就要分成两部分“出去+回来”;出去的话直接利用SPFA(1),1作为起点即可求出每一点的最小花费,回来的话如果是直接利用对每一个人进行SPFA,那么这样肯定超时。仔细想想要求的是每一个点到1的最小距离,那么由于给定的是一个有向图,那么只要重新建图把边反向,那么我们所求的问题就变成1到每一个点的最小距离。所以只要两步SPFA(1)即可。
3 数据类型为long long

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAXN 1000010
#define INF 0x7FFFFFFF

int t , n , m;
long long ans;
int first[MAXN] , next[MAXN];
int star[MAXN] , end[MAXN];
long long value[MAXN];
long long dis[MAXN];
long long tmp[MAXN];
int vis[MAXN];
queue<int>q;

/*初始化*/
void init(){
    memset(first , -1 , sizeof(first));
    memset(next , -1 , sizeof(next));
}

/*SPFA函数*/
void SPFA(int s){
    memset(vis , 0 , sizeof(vis));
    for(int i = 1 ; i <= n ; i++)
       dis[i] = INF;
    dis[s] = 0;
    vis[s] = 1;
    q.push(s);
    while(!q.empty()){
        int x = q.front();
        q.pop();
        vis[x] = 0;
        for(int i = first[x] ; i != -1 ; i = next[i]){
           if(dis[end[i]] > dis[x] + value[i]){
             dis[end[i]] = dis[x] + value[i];
             if(!vis[end[i]]){
               vis[end[i]] = 1;
               q.push(end[i]);
             }
           }
        }
    }
}

int main(){
   int a , b;
   scanf("%d" , &t);
   while(t--){
      scanf("%d%d" , &n , &m);
      /*第一次建图*/
      init();
      for(int i = 0 ; i < m ; i++){
         scanf("%d%d%lld" , &star[i] , &end[i] , &value[i]);
         next[i] = first[star[i]];
         first[star[i]] = i;
      }
      ans = 0;
      SPFA(1);
      memcpy(tmp , dis , sizeof(tmp));/*把ans保存在tmp数组*/
      /*第二次建图*/
      init();
      for(int i = 0 ; i < m ; i++){
         a = star[i];
         b = end[i];
         star[i] = b;
         end[i] = a;
         next[i] = first[star[i]];
         first[star[i]] = i;
      }
      SPFA(1);
      /*求总和*/
      for(int i = 2 ; i <= n ; i++)
         ans += tmp[i]+dis[i];
      printf("%lld\n" , ans);
   }
   return 0;
}
时间: 2024-11-10 07:24:18

hdu 1535 Invitation Cards的相关文章

HDU 1535 Invitation Cards:多源点到单点最短路

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 题目: Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1044    Accepted Submission(s): 459 Problem Description In the age of te

poj 1511 Invitation Cards dijkstra+heap

     最近没有状态,不太难得一题,TLE了3次,WA了1次.      这题主要就是要正向,逆向两次dijkstra,因为稀疏图,所以用heap优化有明显作用.      注意会超出int范围,要用long long     代码太挫了,越写越挫,估计到瓶颈期了 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */

最短路专题【完结】

第一题 hdu 1317 XYZZY 点击打开hdu 1317 思路: 1 题目的图是一个有向图,并且可能存在环.第一个点的能量值为100,边的权值利用能量大小,例如2点为-60,如果1->2那么value[1][2] = -602 题目明确指出如果是要win的话,那么必须是经过的每条边都要大于0.那么我们只要把那些经过松弛操作后的点大于0的入队即可,小于等于0的点肯定不会出现在最终的路径上.3 如果存在正环的话,那么就有能量值无限大,那么这个时候只要判断这个点能否到达n4 判断是否是有环还是五

POJ 最短路问题题号汇总

求最短路基本的算法: 1>Dijkstra算法2>Bellman-Ford算法3>Floyd算法4>Floyd-Warshall算法5>Johnson算法6>A*算法 题目: 1.poj1062 昂贵的聘礼(中等)     此题是个经典题目:用Dijkstra即可:但是其中的等级处理需要一定的技巧:    要理解好那个等级制度:这个处理好,基本就是裸体Dijkstra: 2 poj1125 Stockbroker Grapevine(基本)    这个是简单Floyd,

hdu 1527

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 hint:威佐夫博弈 基本类似于模板 #include <iostream> #include <cmath> #include <cstdio> using namespace std; const double q = (1 + sqrt(5.0)) / 2.0; // 黄金分割数 int Wythoff(int a, int b) { if (a > b)

hdu 2551 竹青遍野

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2551 hint:就是读懂题就行了 #include <iostream> #include <cstdio> using namespace std; typedef long long LL; LL data[1005]; int main() { data[0]=0; for(int i=1; i<1005; i++) data[i]+=data[i-1]+i*i*i; LL

hdu 2054 A == B?

http://acm.hdu.edu.cn/showproblem.php?pid=2054 此题巨坑,刚开始我以为是简单的水题,就用strcmp过, but错了,后来经过我苦思冥想,结果还有几组数据 0.0 和 0,1.000和1.0 , 但是我不太确定前面的0是不是有作用我还是写了,但是有人过的时候,前面的0没考虑比如: 002和2可能是相等的,也可能是不想等的所以不用判断,只能说明hdu数据不是很强啊,嘿嘿 代码如下: #include <iostream> #include <c

hdu 4430 Yukari&#039;s Birthday

点击打开链接hdu 4430 思路:枚举r+二分k 分析: 1 题目要求的是找到一组最小的r*k,如果r*k相同那么就找r最小的. 2 很明显k>=2,根据n <= 10^12,那么可以知道r的最大值r<50,所以只要枚举枚举r的值,然后二分k的大小找到所有的解,存入一个结构体里面,然后在对结构体排序,那么这样就可以得到最后的ans 3 注意题目说了中心点最多一个蜡烛,所以写二分的时候应该注意判断的条件: 4 还有可能计算得到结果超了long long直接变成负数所以应该对或则个进行判断

hdu 1238 Substrings

点击打开链接hdu 1238 思路:kmp+暴力枚举子串 分析: 1 题目要求找到一个子串x,满足x或x的逆串是输入的n个字符串的子串,求最大的x,输出x的长度 2 题目的n最大100,每一个字符串的最大长度为100,那么暴力枚举子串就是o(n^2)才10000肯定是不会超时的,但是由于这里涉及到了逆串的问题,所以我们应该还要求出n个子串的逆串,然后在求最大的x. 代码: #include<iostream> #include<algorithm> #include<cstd