双倍经验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 }
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 }