P1629邮递员送信与P1342请柬与P1821银牛派队研制联合胜利
生活随笔
收集整理的這篇文章主要介紹了
P1629邮递员送信与P1342请柬与P1821银牛派队研制联合胜利
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
P1342 請柬
P1629 郵遞員送信
P1821 [USACO07FEB]銀牛派對Silver Cow Party
三倍經(jīng)驗
這三道題思想比較像的,只不過第一道的數(shù)據(jù)大了很多,于是就成藍題了.
因為如果數(shù)據(jù)小了的話,如第二題和第三題,可以跑n遍最短路.
于是我就來講講第一題的做法.
從起點出發(fā),到每一個節(jié)點,明顯可知這是一個單源多終點的最短路模型.
但是回來的時候,是從多個點回到終點,是一個多源單終點的最短路.
跑floyd任意點間的最短路肯定不行,O(n^3)的時間復雜度.
再來想一想,回來的時候多個點通向同一個點,要是反過來的話,就是單源多終點的最短路了.
于是可以反向存邊,從起點跑到每一個點,dis數(shù)組里就有了從這個點到起點回來時的最短路.
總體來說就是反向存邊跑一遍Dijkstra,正向存邊跑一遍Dijkstra.
代碼如下,挺簡單的就不注釋了(請忽略如"zzq太可愛了"之類的言論).
PS:按照我的習慣,我打每一行都要打個縮進,但是我把vim設置了保持當前縮進,于是復制下來就這樣了......湊合著看吧.
#include<bits/stdc++.h>#define ll long longusing namespace std;priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q1,q2;struct edge {ll next,to,val; }e1[1000010],e2[1000010];ll n,m,size1,size2,ans; ll head1[1000010],head2[1000010]; ll dis1[1000010],dis2[1000010]; bool falg1[1000010],falg2[1000010];void add_edge1(ll,ll,ll); void add_edge2(ll,ll,ll); void Dij1(); void Dij2();int main() {memset(head1,-1,sizeof(head1));memset(head2,-1,sizeof(head2));scanf("%lld%lld",&n,&m);for(ll i=1;i<=m;i++){ll a,b,val;scanf("%lld%lld%lld",&a,&b,&val);add_edge1(a,b,val);add_edge2(b,a,val);}Dij1();Dij2();// for(int i=1;i<=n;i++)printf("%d ",dis1[i]);// printf("\n");// for(int i=1;i<=n;i++)printf("%d ",dis2[i]);for(ll i=2;i<=n;i++)ans+=dis1[i]+dis2[i];printf("%lld\n",ans);return 0; }void add_edge1(ll from,ll to,ll val) {e1[++size1].to=to;e1[size1].val=val;e1[size1].next=head1[from];head1[from]=size1;// printf("zzqtql%d\n",size1); }void add_edge2(ll from,ll to,ll val) {e2[++size2].to=to;e2[size2].val=val;e2[size2].next=head2[from];head2[from]=size2; }void Dij1() {memset(dis1,0x3f,sizeof(dis1));// printf("zzqtkal%d",dis1[3]);memset(falg1,0,sizeof(falg1));dis1[1]=0;q1.push(make_pair(dis1[1],1));while(!q1.empty()){ll x=q1.top().second;q1.pop();if(falg1[x]==true)continue;falg1[x]=true;for(ll i=head1[x];i!=-1;i=e1[i].next){ll val=e1[i].val;ll to=e1[i].to;if(dis1[to]>dis1[x]+val){dis1[to]=dis1[x]+val;q1.push(make_pair(dis1[to],to));}// printf("zzqakioi%d%d\n",val,dis1[to]);}} }void Dij2() {memset(dis2,0x3f,sizeof(dis2));memset(falg2,0,sizeof(falg2));dis2[1]=0;q2.push(make_pair(dis2[1],1));while(!q2.empty()){ll x=q2.top().second;q2.pop();if(falg2[x]==true)continue;falg2[x]=true;for(ll i=head2[x];i!=-1;i=e2[i].next){ll val=e2[i].val;ll to=e2[i].to;if(dis2[to]>dis2[x]+val){dis2[to]=dis2[x]+val;q2.push(make_pair(dis2[to],to));}}} }轉(zhuǎn)載于:https://www.cnblogs.com/Lemir3/p/11059466.html
總結(jié)
以上是生活随笔為你收集整理的P1629邮递员送信与P1342请柬与P1821银牛派队研制联合胜利的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx--安装
- 下一篇: ASP.NET Core EFCore