2019牛客暑期多校训练营(第四场)J free(分层图最短路/模板题)

题目链接:https://ac.nowcoder.com/acm/contest/884/J

题目大意:

  给出一个无向图,每条边对应一个花费,有k次机会能让一条边的花费为0,让求s到t的最短路。

解题报告:

  分层图最短路,就当是模板吧,下面给出两份AC代码。

  建图大概长这样

  

AC代码:

  1.直接暴力建图,花费空间和时间较大。

  语言:C++ 代码长度:2264 运行时间: 269 ms 占用内存:121836K

 1 #include<bits/stdc++.h>
 2 #define numm ch-48
 3 #define pd putchar(' ')
 4 #define pn putchar('\n')
 5 #define pb push_back
 6 #define fi first
 7 #define se second
 8 #define fre1 freopen("1.txt","r",stdin)
 9 #define fre2 freopen("3.txt","w",stdout)
10 #define bug cout<<"*******************"<<endl;
11 #define debug(args...) cout<<#args<<"->"<<args<<"\n";
12 using namespace std;
13 template <typename T>
14 void read(T &res) {
15     bool flag=false;char ch;
16     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
17     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
18     flag&&(res=-res);
19 }
20 template <typename T>
21 void write(T x) {
22     if(x<0) putchar('-'),x=-x;
23     if(x>9) write(x/10);
24     putchar(x%10+'0');
25 }
26 typedef long long ll;
27 typedef unsigned long long ull;
28 const int maxn=9003010; ///n*(k+1)
29 const int maxm=505;
30 const int mod=1e9+7;
31 const int inv2=500000004;
32 const int inf=0x3f3f3f3f;
33 const ll INF=0x3f3f3f3f3f3f3f3f;
34 const int N=32;
35 struct node {
36     int v,net,w;
37 }e[maxn<<2];    ///分层图层和层之前也有边,边*4
38 int head[maxn],dis[maxn],vis[maxn];
39 #define pr pair<int,int>
40 int S,T,cnt;
41 void add(int u,int v,int w) {
42     e[++cnt]={v,head[u],w};
43     head[u]=cnt;
44 }
45 void dijstra() {
46     priority_queue<pr,vector<pr>,greater<pr> >que;
47     memset(dis,inf,sizeof(dis));
48     que.push(make_pair(0,S));
49     dis[S]=0;
50     while(!que.empty()) {
51         int u=que.top().se;que.pop();
52         if(vis[u]) continue;
53         vis[u]=true;
54         for(int i=head[u];~i;i=e[i].net) {
55             int v=e[i].v,w=e[i].w;
56             if(!vis[v]&&dis[v]>dis[u]+w) {
57                 dis[v]=dis[u]+w;
58                 que.push(make_pair(dis[v],v));
59             }
60         }
61     }
62 }
63 int main()
64 {
65 //    #define local
66     #ifdef local
67         fre1;
68         fre2;
69     #endif // local
70     int n,m,k;
71     memset(head,-1,sizeof(head));
72     read(n),read(m),read(S),read(T),read(k);
73     for(int i=1;i<=m;i++) {
74         int u,v,w;
75         read(u),read(v),read(w);
76         for(int j=0;j<=k;j++) {
77             add(u+j*n,v+j*n,w);
78             add(v+j*n,u+j*n,w);
79             if(j!=k) {
80                 add(u+j*n,v+(j+1)*n,0);
81                 add(v+j*n,u+(j+1)*n,0);
82             }
83         }
84     }
85     dijstra();
86     int minn=inf;
87     for(int i=0;i<=k;i++)
88         minn=min(minn,dis[T+i*n]);
89     write(minn);pn;
90     return 0;
91 }

  2.用数组标记状态,省空间也省时间

  语言:C++ 代码长度:2374 运行时间: 214 ms 占用内存:43628K

 1 #include<bits/stdc++.h>
 2 #define numm ch-48
 3 #define pd putchar(' ')
 4 #define pn putchar('\n')
 5 #define pb push_back
 6 #define fi first
 7 #define se second
 8 #define fre1 freopen("1.txt","r",stdin)
 9 #define fre2 freopen("3.txt","w",stdout)
10 #define bug cout<<"*******************"<<endl;
11 #define debug(args...) cout<<#args<<"->"<<args<<"\n";
12 using namespace std;
13 template <typename T>
14 void read(T &res) {
15     bool flag=false;char ch;
16     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
17     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
18     flag&&(res=-res);
19 }
20 template <typename T>
21 void write(T x) {
22     if(x<0) putchar('-'),x=-x;
23     if(x>9) write(x/10);
24     putchar(x%10+'0');
25 }
26 typedef long long ll;
27 typedef unsigned long long ull;
28 const int maxn=3010; ///n*(k+1)
29 const int maxm=505;
30 const int mod=1e9+7;
31 const int inv2=500000004;
32 const int inf=0x3f3f3f3f;
33 const ll INF=0x3f3f3f3f3f3f3f3f;
34 const int N=32;
35 struct node {
36     int v,net,w;
37 }e[maxn<<1];    ///分层图层和层之前也有边,边*4
38 int head[maxn];
39 int dis[maxn][maxn],vis[maxn][maxn];
40 ///dis[i][k],用掉k次机会到达i点的花费
41 #define pr pair<int,int>
42 int S,T,cnt,n,k;
43 void add(int u,int v,int w) {
44     e[++cnt]={v,head[u],w};
45     head[u]=cnt;
46 }
47 void dijstra() {
48     priority_queue<pr,vector<pr>,greater<pr> >que;
49     memset(dis,inf,sizeof(dis));
50     que.push(make_pair(0,S-1));
51     dis[S][0]=0;
52     while(!que.empty()) {
53         int u=que.top().se;que.pop();
54         int c=u/n;u=u%n+1;
55         if(vis[u][c]) continue;
56         vis[u][c]=true;
57         for(int i=head[u];~i;i=e[i].net) {
58             int v=e[i].v,w=e[i].w;
59             if(!vis[v][c]&&dis[v][c]>dis[u][c]+w) {  ///先不用机会到达下一顶点
60                 dis[v][c]=dis[u][c]+w;
61                 que.push(make_pair(dis[v][c],v-1+c*n));
62             }
63             if(c!=k&&!vis[v][c+1]&&dis[v][c+1]>dis[u][c]) {
64                 dis[v][c+1]=dis[u][c];
65                 que.push(make_pair(dis[v][c+1],v-1+(c+1)*n));
66             }
67         }
68     }
69 }
70 int main()
71 {
72 //    #define local
73     #ifdef local
74         fre1;
75         fre2;
76     #endif // local
77     int m;
78     memset(head,-1,sizeof(head));
79     read(n),read(m),read(S),read(T),read(k);
80     for(int i=1;i<=m;i++) {
81         int u,v,w;
82         read(u),read(v),read(w);
83         add(u,v,w);
84         add(v,u,w);
85     }
86     dijstra();
87     int minn=inf;
88     for(int i=0;i<=k;i++)
89         minn=min(minn,dis[T][i]);
90     write(minn);pn;
91     return 0;
92 }

猜你喜欢

转载自www.cnblogs.com/wuliking/p/11376419.html