蓝书3.2 最短路

T1 银牛派对 luogu 1821

题目大意:

一个有向图

求任意节点到定点的最短距离+定点到该点的最短距离之和的最大值

思路:

正反dij

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 100100
12 #define eps 1e-5
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int ans,n,m,s,dis[MAXN],vis[MAXN],Dis[MAXN],Vis[MAXN];
22 int to[MAXN],nxt[MAXN],val[MAXN],fst[MAXN],cnt;
23 int To[MAXN],Nxt[MAXN],Val[MAXN],Fst[MAXN],Cnt;
24 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
25 void Add(int u,int v,int w) {Nxt[++Cnt]=Fst[u],Fst[u]=Cnt,To[Cnt]=v,Val[Cnt]=w;}
26 struct node
27 {
28     int id,val;
29     bool operator < (const node &a) const
30     {
31         return val>a.val;
32     }
33 };
34 priority_queue <node> q,Q;
35 void dij()
36 {
37     memset(dis,127,sizeof(dis));
38     dis[s]=0;q.push((node){s,0});int x;
39     while(!q.empty())
40     {
41         x=q.top().id;q.pop();
42         if(vis[x]) continue;vis[x]=1;
43         for(int i=fst[x];i;i=nxt[i])
44             if(dis[to[i]]>dis[x]+val[i]) {dis[to[i]]=dis[x]+val[i];q.push((node){to[i],dis[to[i]]});}
45     }
46 }
47 void Dij()
48 {
49     memset(Dis,127,sizeof(Dis));
50     Dis[s]=0;Q.push((node){s,0});int x;
51     while(!Q.empty())
52     {
53         x=Q.top().id;Q.pop();
54         if(Vis[x]) continue;Vis[x]=1;
55         for(int i=Fst[x];i;i=Nxt[i])
56             if(Dis[To[i]]>Dis[x]+Val[i]) {Dis[To[i]]=Dis[x]+Val[i];Q.push((node){To[i],Dis[To[i]]});}
57     }
58 }
59 int main()
60 {
61     n=read(),m=read(),s=read();int a,b,c;
62     while(m--) {a=read(),b=read(),c=read();add(a,b,c);Add(b,a,c);}
63     dij();Dij();
64     for(int i=1;i<=n;i++)
65         if(i!=s&&dis[i]!=inf&&Dis[i]!=inf) ans=max(ans,dis[i]+Dis[i]);
66     printf("%d",ans);
67 }
View Code

T2 Roadblocks poj 3255

题目大意:

求次短路

思路:

开一个dis的同时开一个次短路数组

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 100100
12 #define eps 1e-5
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,dis[MAXN],subdis[MAXN],vis[MAXN],q[MAXN],l,r;
22 int to[MAXN],nxt[MAXN],val[MAXN],fst[MAXN],cnt;
23 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
24 void spfa()
25 {
26     memset(dis,127,sizeof(dis));
27     memset(subdis,127,sizeof(subdis));
28     q[++r]=1,dis[1]=0,vis[1]=1;
29     while(l<=r)
30     {
31         int x=q[l++];vis[x]=0;
32         for(int i=fst[x];i;i=nxt[i])
33         {
34             if(dis[to[i]]>dis[x]+val[i])
35             {
36                 subdis[to[i]]=dis[to[i]],dis[to[i]]=dis[x]+val[i];
37                 if(!vis[to[i]]) vis[to[i]]=1,q[++r]=to[i];
38             }
39             if(subdis[to[i]]>subdis[x]+val[i])
40             {
41                 subdis[to[i]]=subdis[x]+val[i];
42                 if(!vis[to[i]]) vis[to[i]]=1,q[++r]=to[i];
43             }
44             if(dis[to[i]]<dis[x]+val[i]&&subdis[to[i]]>dis[x]+val[i])
45             {
46                 subdis[to[i]]=dis[x]+val[i];
47                 if(!vis[to[i]]) vis[to[i]]=1,q[++r]=to[i];
48             }
49         }
50     }
51 }
52 int main()
53 {
54     n=read(),m=read();int a,b,c;
55     while(m--){a=read(),b=read(),c=read();add(a,b,c);add(b,c,a);}
56     spfa();printf("%d",subdis[n]);
57 }
View Code

T3 最短路计数 luogu 1144

题目大意:

求有多少种最短路

思路:

spfa的同时记录有多少种情况

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 1001000
12 #define MOD 100003
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,dis[MAXN],vis[MAXN],q[MAXN],l,r,ans[MAXN];
22 int to[MAXN<<2],nxt[MAXN<<2],fst[MAXN],cnt;
23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
24 void spfa()
25 {
26     memset(dis,127,sizeof(dis));
27     q[++r]=1,dis[1]=0,ans[1]=vis[1]=1;
28     while(l<=r)
29     {
30         int x=q[l++];
31         for(int i=fst[x];i;i=nxt[i])
32             if(dis[to[i]]==dis[x]+1) (ans[to[i]]+=ans[x])%=MOD;
33             else if(dis[to[i]]>dis[x]+1)
34             {
35                 ans[to[i]]=ans[x],dis[to[i]]=dis[x]+1;
36                 if(!vis[to[i]]) vis[to[i]]=1,q[++r]=to[i];
37             }
38         vis[x]=0;
39     }
40 }
41 int main()
42 {
43     n=read(),m=read();int a,b,c;
44     while(m--){a=read(),b=read();add(a,b);add(b,a);}
45     spfa();
46     for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
47 }
View Code

T4 最优贸易 luogu 1073

题目大意:

一个有向图 在一条路径上可以在一个点以该点的价格买入商品 在该点之后在另一个点卖出 求最大利润

思路:

dfs居然就过了

dfs的同时维护经过的最小值 并对每个点维护一个dp值记录利润

每当一个点经过的最小值与dp值不被更新时 就可以结束dfs了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 1001000
12 #define MOD 100003
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,dp[MAXN],mn[MAXN],g[MAXN];
22 int to[MAXN<<2],nxt[MAXN<<2],fst[MAXN],cnt;
23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
24 void dfs(int x,int mnx,int las)
25 {
26     int fl=1;
27     mnx=min(g[x],mnx);
28     if(mn[x]>mnx) mn[x]=mnx,fl=0;
29     if(max(dp[las],g[x]-mnx)>dp[x]) dp[x]=max(dp[las],g[x]-mnx),fl=0;
30     if(fl) return;
31     for(int i=fst[x];i;i=nxt[i]) dfs(to[i],mnx,x);
32 }
33 
34 int main()
35 {
36     n=read(),m=read();int a,b,c;
37     for(int i=1;i<=n;i++) g[i]=read();
38     memset(mn,127,sizeof(mn));
39     for(int i=1;i<=m;i++){a=read(),b=read(),c=read();add(a,b);if(c==2) add(b,a);}
40     dfs(1,inf,0);
41     printf("%d\n",dp[n]);
42 }
View Code

T5 汽车加油行驶

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/9358821.html