日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

POJ 1511 Invitation Cards——Dijkstra优先队列优化+反向建图

發(fā)布時(shí)間:2023/11/30 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 1511 Invitation Cards——Dijkstra优先队列优化+反向建图 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【題目描述】

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.
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

【題目分析】
求的是從源點(diǎn)到所有點(diǎn)以及所有點(diǎn)到源點(diǎn)的路程和最小,對(duì)于源點(diǎn)到所有點(diǎn)的路程和最小我們很自然的想到Dijkstra,因?yàn)閿?shù)據(jù)規(guī)模比較大需要用鄰接表,我用的是前向星的方式進(jìn)行儲(chǔ)存,雖然用vector也可以,但是聽(tīng)說(shuō)vector更有可能MLE(因?yàn)镾TL中vector實(shí)際要多用一倍的空間)和TLE(因?yàn)関ector的一些挺簡(jiǎn)單的操作耗時(shí)比一般數(shù)組要長(zhǎng))。
但是對(duì)于其他所有的點(diǎn)到源點(diǎn)的路程和最小我們直接用Dijkstra顯然是不行的,而用Floyed復(fù)雜度太高。
這個(gè)時(shí)候就需要一點(diǎn)點(diǎn)腦洞想到反向建圖(圖論中反向建圖經(jīng)常會(huì)碰到,很多正面看起來(lái)難以解決的問(wèn)題反過(guò)來(lái)看就會(huì)變的簡(jiǎn)單起來(lái)),反向建圖后我們?cè)倥芤槐镈ijkstra,這時(shí)候的路徑方向全部反過(guò)來(lái)就是實(shí)際上其他所有點(diǎn)到源點(diǎn)的路徑。然后再求和就可以啦。
前向星進(jìn)行儲(chǔ)存的時(shí)候要注意head數(shù)組(保存每個(gè)點(diǎn)第一條邊的數(shù)組)如果初始化為0,邊一定要從1開(kāi)始,否則無(wú)法判斷到底是沒(méi)有邊了還是指向第一個(gè)邊,如果習(xí)慣從0開(kāi)始數(shù)邊應(yīng)該將head數(shù)組初始化為-1.
將結(jié)構(gòu)體作為優(yōu)先隊(duì)列的元素的時(shí)候需要進(jìn)行運(yùn)算符重載,優(yōu)先隊(duì)列默認(rèn)是使用小于號(hào)進(jìn)行比較的,我們應(yīng)該對(duì)小于號(hào)進(jìn)行重載。如果想要按照某個(gè)值從大到小重載后還是小于號(hào),如果想要某個(gè)值從小到大應(yīng)該重載為大于號(hào),這是因?yàn)閮?yōu)先隊(duì)列默認(rèn)是從大到小的,也就是“重載后值越小”的越在后面。
在對(duì)Dijkstra用優(yōu)先隊(duì)列優(yōu)化的時(shí)候不要進(jìn)行初始化,也不要將源點(diǎn)設(shè)置為已經(jīng)訪問(wèn)過(guò),如果設(shè)為已經(jīng)訪問(wèn)過(guò)就直接退出了。而將dis數(shù)組進(jìn)行初始化以后我們后面就很有可能沒(méi)有辦法將其他節(jié)點(diǎn)放入隊(duì)列。
【AC代碼】

/* *因?yàn)閷蓚€(gè)過(guò)程分別寫(xiě)出來(lái)了顯得有點(diǎn)丑,空間也有點(diǎn)大 *我們也可以兩次建圖,用一套數(shù)組就好了 */ #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #include<climits> #include<queue> #include<vector> #include<set> #include<map> using namespace std;typedef long long ll; const int MAXN=1e6+5; struct node {int v,next;ll w;node(int _v=0,int _next=0,ll _w=0):v(_v),w(_w),next(_next){} }Edge1[MAXN],Edge2[MAXN]; struct qnode {int x; ll d;qnode(int _x=0,ll _d=0):x(_x),d(_d){}bool operator <(const qnode &r)const {return d>r.d;} }p; int head1[MAXN],head2[MAXN],tot1,tot2; bool vis[MAXN]; ll dis1[MAXN],dis2[MAXN],ans; int n,m;void AddEdge1(int u,int v,ll w) {tot1++;Edge1[tot1].v=v; Edge1[tot1].w=w; Edge1[tot1].next=head1[u];head1[u]=tot1; }void AddEdge2(int u,int v,int w) {tot2++;Edge2[tot2].v=v; Edge2[tot2].w=w; Edge2[tot2].next=head2[u];head2[u]=tot2; }void Dijkstra1() {memset(vis,0,sizeof(vis));memset(dis1,0x3f,sizeof(dis1));const int INF=dis1[1];int u,v;// for(int i=head1[1];i;i=Edge1[i].next)// {// dis1[Edge1[i].v]=Edge1[i].w;// }dis1[1]=0;//vis[1]=true;priority_queue<qnode> q;q.push(qnode(1,0));while(!q.empty()){p=q.top(); q.pop();if(vis[p.x]) continue;vis[p.x]=true;u=p.x;for(int i=head1[u];i;i=Edge1[i].next){v=Edge1[i].v;if(!vis[v] && dis1[v]>dis1[u]+Edge1[i].w){dis1[v]=dis1[u]+Edge1[i].w;q.push(qnode(v,dis1[v]));}}} }void Dijkstra2() {memset(vis,0,sizeof(vis));memset(dis2,0x3f,sizeof(dis2));const int INF=dis2[1];int u,v;// for(int i=head2[1];i;i=Edge2[i].next)// {// dis2[Edge2[i].v]=Edge2[i].w;// }dis2[1]=0; //vis[1]=true;priority_queue<qnode> q;q.push(qnode(1,0));while(!q.empty()){p=q.top(); q.pop();if(vis[p.x]) continue;vis[p.x]=true;u=p.x;for(int i=head2[u];i;i=Edge2[i].next){v=Edge2[i].v;if(!vis[v] && dis2[v]>dis2[u]+Edge2[i].w){dis2[v]=dis2[u]+Edge2[i].w;q.push(qnode(v,dis2[v]));}}} }void test() {for(int i=1;i<=n;i++){printf("%lld ",dis1[i]);}printf("\n");for(int i=1;i<=n;i++){printf("%lld ",dis2[i]);}printf("\n"); }int main() {int T,u,v; ll w;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);tot1=0; tot2=0;memset(head1,0,sizeof(head1));memset(head2,0,sizeof(head2));for(int i=0;i<m;i++){scanf("%d%d%lld",&u,&v,&w);AddEdge1(u,v,w); AddEdge2(v,u,w);}Dijkstra1(); Dijkstra2();//test();ans=0;for(int i=1;i<=n;i++){ans+=dis1[i]+dis2[i];}printf("%lld\n",ans);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的POJ 1511 Invitation Cards——Dijkstra优先队列优化+反向建图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。