BZOJ 2662&&2763

双倍经验2333....

了解到这是典型的分层图最短路,k次免费机会就有k层图,层与层之间边权是0,然后其他边照样建,跑最短路就行了.

2662边权减半同理呀。。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 #define ln printf("\n")
11 const int N=1e6+2e5+50;
12 const int MOD=1e9+7;
13 using namespace std;
14 int n,m,k;
15 int x,y,z,_x,_y,x_,y_;
16 int s,t;
17 int tot=0;
18 int head[N],dis[N];
19 bool vis[N];
20 int ans=23333333;
21 struct node
22 {
23     int to,nxt,cost;
24 }edge[N<<1];
25 struct dist
26 {
27     int h,id;
28     bool operator<(const dist&a)const{
29       return a.h<h;
30     }
31 };
32 int read()
33 {
34     int s=0,t=1; char c;
35     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
36     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
37     return s*t;
38 }
39 ll readl()
40 {
41     ll s=0,t=1; char c;
42     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
43     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
44     return s*t;
45 }
46 void add(int x,int y,int z)
47 {
48     edge[++tot].to=y;
49     edge[tot].cost=z;
50     edge[tot].nxt=head[x];
51     head[x]=tot;
52 }
53 priority_queue<dist>q;
54 void Dijkstra(int s,int t)
55 {
56     int x,y,z;
57     memset(dis,127,sizeof(dis));
58     memset(vis,false,sizeof(vis));
59     dis[s]=0;
60     dist p;
61     p.h=0; p.id=s;
62     q.push(p);
63     while (!q.empty()){
64       p=q.top(); q.pop();
65       x=p.id;
66       if (!vis[x]){
67         vis[x]=true;
68         for (int i=head[x];i;i=edge[i].nxt){
69           y=edge[i].to; z=edge[i].cost;
70           if (dis[y]>dis[x]+z) {
71               dis[y]=dis[x]+z;
72               p.h=dis[y]; p.id=y;
73               q.push(p);
74           }
75         }
76       }
77     }
78     for (int i=0;i<=k;i++)
79       ans=min(ans,dis[t+i*n]);
80 }
81 int main()
82 {
83     n=read(),m=read(),k=read();
84     s=1,t=n;
85     for (int i=1;i<=m;i++){
86       x=read(),y=read(),z=read();
87       add(x,y,z); add(y,x,z);
88       for (int j=1;j<=k;j++){
89             _x=x+(j-1)*n; _y=y+(j-1)*n;
90           x_=x+j*n,y_=y+j*n;
91           add(x_,y_,z),add(y_,x_,z);
92           add(_x,y_,(z>>1)),add(_y,x_,(z>>1));
93         }
94     }
95     Dijkstra(s,t);
96     out(ans);
97     return 0;
98 }
2662
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 #define ln printf("\n")
11 const int N=1e6+2e5+50;
12 const int MOD=1e9+7;
13 using namespace std;
14 int n,m,k;
15 int x,y,z,_x,_y,x_,y_;
16 int s,t;
17 int tot=0;
18 int head[N],dis[N];
19 bool vis[N];
20 int ans=23333333;
21 struct node
22 {
23     int to,nxt,cost;
24 }edge[N<<1];
25 struct dist
26 {
27     int h,id;
28     bool operator<(const dist&a)const{
29       return a.h<h;
30     }
31 };
32 int read()
33 {
34     int s=0,t=1; char c;
35     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
36     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
37     return s*t;
38 }
39 ll readl()
40 {
41     ll s=0,t=1; char c;
42     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
43     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
44     return s*t;
45 }
46 void add(int x,int y,int z)
47 {
48     edge[++tot].to=y;
49     edge[tot].cost=z;
50     edge[tot].nxt=head[x];
51     head[x]=tot;
52 }
53 priority_queue<dist>q;
54 void Dijkstra(int s,int t)
55 {
56     int x,y,z;
57     memset(dis,127,sizeof(dis));
58     memset(vis,false,sizeof(vis));
59     dis[s]=0;
60     dist p;
61     p.h=0; p.id=s;
62     q.push(p);
63     while (!q.empty()){
64       p=q.top(); q.pop();
65       x=p.id;
66       if (!vis[x]){
67         vis[x]=true;
68         for (int i=head[x];i;i=edge[i].nxt){
69           y=edge[i].to; z=edge[i].cost;
70           if (dis[y]>dis[x]+z) {
71               dis[y]=dis[x]+z;
72               p.h=dis[y]; p.id=y;
73               q.push(p);
74           }
75         }
76       }
77     }
78     for (int i=0;i<=k;i++)
79       ans=min(ans,dis[t+i*n]);
80 }
81 int main()
82 {
83     n=read(),m=read(),k=read();
84     s=read(),t=read();
85     for (int i=1;i<=m;i++){
86       x=read(),y=read(),z=read();
87       add(x,y,z); add(y,x,z);
88       for (int j=1;j<=k;j++){
89             _x=x+(j-1)*n; _y=y+(j-1)*n;
90           x_=x+j*n,y_=y+j*n;
91           add(x_,y_,z),add(y_,x_,z);
92           add(_x,y_,0),add(_y,x_,0);
93         }
94     }
95     Dijkstra(s,t);
96     out(ans);
97     return 0;
98 }
2763

 

转载于:https://www.cnblogs.com/Kaleidoscope233/p/9570734.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值