POJ1511
Invitation Cards
Time Limit: 8000MS | Memory Limit: 262144K | |
Total Submissions: 14928 | Accepted: 4831 |
Description
In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all the necessary information and with the programme. A lot of students were hired to distribute these invitations among the people. Each student volunteer has assigned exactly one bus stop and he or she stays there the whole day and gives invitation to people travelling by bus. A special course was taken where students learned how to influence people and what is the difference between influencing and robbery.
The transport system is very special: all lines are unidirectional and connect exactly two stops. Buses leave the originating stop with passangers each half an hour. After reaching the destination stop they return empty to the originating stop, where they wait until the next full half an hour, e.g. X:00 or X:30, where 'X' denotes the hour. The fee for transport between two stops is given by special tables and is payable on the spot. The lines are planned in such a way, that each round trip (i.e. a journey starting and finishing at the same stop) passes through a Central Checkpoint Stop (CCS) where each passenger has to pass a thorough check including body scan.
All the ACM student members leave the CCS each morning. Each volunteer is to move to one predetermined stop to invite passengers. There are as many volunteers as stops. At the end of the day, all students travel back to CCS. You are to write a computer program that helps ACM to minimize the amount of money to pay every day for the transport of their employees.
The transport system is very special: all lines are unidirectional and connect exactly two stops. Buses leave the originating stop with passangers each half an hour. After reaching the destination stop they return empty to the originating stop, where they wait until the next full half an hour, e.g. X:00 or X:30, where 'X' denotes the hour. The fee for transport between two stops is given by special tables and is payable on the spot. The lines are planned in such a way, that each round trip (i.e. a journey starting and finishing at the same stop) passes through a Central Checkpoint Stop (CCS) where each passenger has to pass a thorough check including body scan.
All the ACM student members leave the CCS each morning. Each volunteer is to move to one predetermined stop to invite passengers. There are as many volunteers as stops. At the end of the day, all students travel back to CCS. You are to write a computer program that helps ACM to minimize the amount of money to pay every day for the transport of their employees.
Input
The
input consists of N cases. The first line of the input contains only
positive integer N. Then follow the cases. Each case begins with a line
containing exactly two integers P and Q, 1 <= P,Q <= 1000000. P is
the number of stops including CCS and Q the number of bus lines. Then
there are Q lines, each describing one bus line. Each of the lines
contains exactly three numbers - the originating stop, the destination
stop and the price. The CCS is designated by number 1. Prices are
positive integers the sum of which is smaller than 1000000000. You can
also assume it is always possible to get from any stop to any other
stop.
Output
For
each case, print one line containing the minimum amount of money to be
paid each day by ACM for the travel costs of its volunteers.
Sample Input
2 2 2 1 2 13 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
Source
思路:这题就是要求从点1到其他各个点,然后从其他各个点回到点1的最小总距离。很明显,首先会想到DIJ,但是这题用DIJ速度太慢了。因为DIJ的复杂度是O(N^2)的。用FLOYD也不行,因为FLOYD需要使用邻接矩阵,但是这而N太大了。不能使用建立这么大的邻接矩阵。然后就剩下Bellman-fordl和SPFA了。这个里面Bellman-ford的复杂度明显比SPFA高。所以,我们使用SPFA+邻接表+逆邻接表解决这个问题。在求其他点到点1的距离时,使用逆邻接表存储,只要SPFA就可以求出来了。而如果不这样,就需要每一次,求出点X(X!=1)到其他点的距离,然后选择到点1的距离。不断这样的循环,需要N-1次。而使用逆邻接表只需要一次就可以了。另外:注意 本题不要使用STL否则会超时。本题邻接和逆邻接链表都需要使用静态的。
1 #include <cstdlib> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <cctype> 7 8 9 10 #define MAXCOST 1000000001 11 #define MAX_Q_SIZE 1000000+4 12 13 14 using namespace std; 15 16 struct Node{ 17 int v; 18 int cost; 19 int next; 20 21 }; 22 23 24 25 int d[1000000+4]; 26 27 28 29 Node node[2000000+4]; 30 int begin,end; 31 int vt[1000000+4]; 32 33 int revt[1000000+4]; 34 35 36 37 38 39 40 41 template <typename first_type> 42 class queue{ 43 first_type q[MAX_Q_SIZE]; 44 int begin,end; 45 int maxsize; 46 int cursize; 47 48 49 public : 50 51 queue() 52 {begin=end=0;maxsize=MAX_Q_SIZE-1;cursize=0;} 53 54 55 56 int empty() 57 {if(cursize<=0) 58 return 1; 59 return 0; 60 } 61 62 int clear() 63 {begin=end=0;maxsize=MAX_Q_SIZE-1;cursize=0;return 1;} 64 65 66 int pop() 67 {if(cursize<=0) 68 return 0; 69 begin++; 70 cursize--; 71 return 1; 72 } 73 74 int size() 75 {if(cursize<=0) 76 return 0; 77 return cursize; 78 } 79 80 int push(first_type x) 81 {if(cursize>=maxsize) 82 return 0; 83 q[end++]=x; 84 cursize++; 85 return 1; 86 } 87 88 first_type front() 89 { 90 if(cursize<=0) 91 return NULL; 92 return q[begin]; 93 } 94 95 }; 96 97 98 99 queue<int>q; 100 101 102 103 104 105 106 107 108 109 int main(int argc, char *argv[]) 110 { 111 112 int n; 113 114 int i,j,k; 115 116 int m; 117 118 int t; 119 120 scanf("%d",&t); 121 122 123 while(t--) 124 { 125 scanf("%d%d",&n,&m); 126 begin=end=0; 127 128 for(i=1;i<=n;i++) 129 {revt[i]=-1;vt[i]=-1;} 130 131 132 133 q.clear(); 134 for(i=1;i<=m;i++) 135 { 136 int a,b; 137 long long cost; 138 scanf("%d%d%d",&a,&b,&cost); 139 Node tmp; 140 tmp.v=b; 141 tmp.cost=cost; 142 143 144 int tt=vt[a]; 145 tmp.next=tt; 146 node[begin]=tmp; 147 begin++; 148 vt[a]=begin-1; 149 150 151 tmp.v=a; 152 tt=revt[b]; 153 tmp.next=tt; 154 node[begin]=tmp; 155 begin++; 156 revt[b]=begin-1; 157 158 159 160 161 } 162 163 164 165 int lowcost=MAXCOST; 166 long long sumcost=0; 167 168 169 170 171 172 173 k=1; 174 for(i=1;i<=n;i++) 175 {d[i]=MAXCOST;} 176 177 178 179 q.clear(); 180 int it; 181 for(it=vt[k];it!=-1;it=node[it].next) 182 {d[node[it].v]=node[it].cost;q.push(node[it].v); 183 } 184 185 186 187 188 while(!q.empty()) 189 { 190 int x=q.front(); 191 q.pop(); 192 for(it=vt[x];it!=-1;it=node[it].next) 193 { 194 if(d[node[it].v]>d[x]+node[it].cost) 195 {d[node[it].v]=d[x]+node[it].cost;q.push(node[it].v); 196 197 } 198 } 199 200 } 201 202 203 204 int y; 205 for(y=2;y<=n;y++) 206 {sumcost+=d[y];} 207 208 209 210 211 212 213 214 215 216 217 218 for(i=1;i<=n;i++) 219 {d[i]=MAXCOST;} 220 221 222 223 q.clear(); 224 225 for(it=revt[k];it!=-1;it=node[it].next) 226 {d[node[it].v]=node[it].cost; 227 q.push(node[it].v); 228 229 } 230 231 232 233 234 while(!q.empty()) 235 { 236 int x=q.front(); 237 q.pop(); 238 for(it=revt[x];it!=-1;it=node[it].next) 239 { 240 if(d[node[it].v]>d[x]+node[it].cost) 241 {d[node[it].v]=d[x]+node[it].cost; 242 q.push(node[it].v);// 243 244 } 245 } 246 247 } 248 249 250 251 252 for(y=2;y<=n;y++) 253 {sumcost+=d[y];} 254 255 256 257 258 259 260 261 262 263 264 265 // printf("%lld\n",sumcost); 266 cout<<sumcost<<endl; 267 268 } 269 270 271 272 273 274 275 //system("PAUSE"); 276 return EXIT_SUCCESS; 277 }