2016huasacm暑假集训训练三 D - Invitation Cards

题目链接:https://vjudge.net/contest/123674#problem/D

题意:一张个向图,求从点1开始到其他各点的最短路权值和加上从其他各点到点1的最短路权值和 首先注意的是这是一个有向图,既要求1到所有的点的距离又要求其他所有点到1的距离,由于只学过spfa算法,就又用了spfa算法,求1到其他点的距离比较好求,但其他点到1的距离就不太好求了,我用到了图的转置,就是把所有的边的方向都反向,给建立一个新的图,这样1以外的点到1的距离就是1到1以外的点的距离;  

  用习惯了Java还真不习惯c++,特别是看到指针就烦,但Java这时间也真吓人的,

AC代码: time: 21282ms  好可怕!

  1 import java.util.*;
  2 import java.io.*;
  3 
  4 public class Main {
  5     public static Ver[] array1;
  6     public static Ver[] array2;
  7     public static int[] head1;
  8     public static int[] head2;
  9     public static int n;
 10     public static long[] dis1;
 11     public static long[] dis2;
 12     public static boolean[] judge;
 13     public static long Max = 999999999;
 14     public static long[] result;
 15     public static int count;
 16 
 17     /**
 18      * @param args
 19      */
 20     public static void main(String[] args) throws IOException {
 21         // TODO Auto-generated method stub
 22         Scanner s = new Scanner(new BufferedInputStream(System.in));
 23         int t = s.nextInt();
 24 
 25         while (t-- > 0) {
 26 
 27             n = s.nextInt();
 28             int m = s.nextInt();
 29             array1 = new Ver[1000002];
 30             array2 = new Ver[1000002];
 31             head1 = new int[n + 1];
 32             head2 = new int[n + 1];
 33             count = 1;
 34             for (int i = 0; i < m; i++) {   //建图
 35                 int a = s.nextInt();
 36                 int b = s.nextInt();            
 37                 long c = s.nextLong();            
 38                 array1[count] = new Ver(b, c);          //正图
 39                 array1[count].next = head1[a];
 40                 head1[a] = count;
 41                 
 42                 
 43                 array2[count] = new Ver(a, c);    //反图
 44                 array2[count].next = head2[b];
 45                 head2[b] = count;
 46                 count++;
 47             }
 48             result = new long[n + 1];
 49             spfa1(1);
 50             spfa2(1);
 51             long ans = 0;
 52             for (int i = 2; i <= n; i++) {           //求和
 53                 ans += dis1[i] + dis2[i];
 54             }
 55             System.out.println(ans);
 56         }
 57         s.close();
 58     }
 59 
 60     public static void spfa2(int a) {      //反向图的spfa算法
 61         dis2 = new long[n + 1];
 62         judge = new boolean[n + 1];
 63         for (int i = 1; i < n + 1; i++) {
 64             dis2[i] = Max;
 65 
 66         }
 67         LinkedList<Integer> queue = new LinkedList<Integer>();
 68         judge[1] = true;
 69         dis2[1] = 0;
 70         queue.add(1);
 71         while (!queue.isEmpty()) {
 72             int vpoll = queue.poll();
 73             judge[vpoll] = false;
 74 
 75             int temp = head2[vpoll];
 76             while (temp != 0) {
 77                 if (relax2(vpoll, array2[temp].value, array2[temp].distance)) {
 78                     if (!judge[array2[temp].value]) {
 79                         judge[array2[temp].value] = true;
 80                         queue.add(array2[temp].value);
 81                     }
 82                 }
 83                 temp = array2[temp].next;
 84             }
 85         }
 86 
 87     }
 88 
 89     public static void spfa1(int a) {     //正向图的spfa算法
 90         dis1 = new long[n + 1];
 91         judge = new boolean[n + 1];
 92         for (int i = 1; i < n + 1; i++) {
 93             dis1[i] = Max;
 94 
 95         }
 96         LinkedList<Integer> queue1 = new LinkedList<Integer>();
 97         judge[a] = true;
 98         dis1[a] = 0;
 99         queue1.add(a);
100         while (!queue1.isEmpty()) {
101             int vpoll = queue1.poll();
102             judge[vpoll] = false;
103 
104             int temp = head1[vpoll];
105             while (temp != 0) {
106                 if (relax1(vpoll, array1[temp].value, array1[temp].distance)) {
107                     if (!judge[array1[temp].value]) {
108                         judge[array1[temp].value] = true;
109                         queue1.add(array1[temp].value);
110                     }
111                 }
112                 temp = array1[temp].next;
113             }
114         }
115 
116     }
117 
118     public static boolean relax1(int a, int b, long c) {
119 
120         if (dis1[a] + c < dis1[b]) {
121             dis1[b] = dis1[a] + c;
122             return true;
123         }
124         return false;
125     }
126 
127     public static boolean relax2(int a, int b, long c) {
128 
129         if (dis2[a] + c < dis2[b]) {
130             dis2[b] = dis2[a] + c;
131             return true;
132         }
133         return false;
134     }
135 
136 }
137 
138 class Ver {                                  //图类
139     long distance;
140     int value;
141     int next;
142 
143     Ver(int value, long distance) {
144         this.value = value;
145         this.distance = distance;
146     }
147 }

 

 

 

 

转载于:https://www.cnblogs.com/LIUWEI123/p/5718923.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值