P1850 换教室
首先说一个坑:
有自环,有重边
难受,直接邻接表
接着dp
分类讨论即可
四类,分别求和
代码:
#include<bits/stdc++.h> using namespace std; const int N=305,MAXN=2005; #define dl double int n,m,v,e; int c[MAXN],d[MAXN]; dl k[MAXN]; dl F[MAXN][2],G[MAXN][2]; dl f[N][N];//f[i][j][k]表示前i个,换j节课,现在在第c/d个教室所用最短路程 bool used[N]; dl dis[N]; int FF[N][N]; int hed[MAXN]={0},tal[MAXN],val[MAXN],nxt[MAXN],cnt=0; void dijkstra(){ for(int i=1;i<=v;i++){ memset(used,0,sizeof(used)); for(int j=0;j<N;j++) dis[j]=2000000000.0; dis[i]=0.00; for(int j=1;j<=v;j++){ int u=0; for(int k=1;k<=v;k++){ if(!used[k]&&dis[k]<dis[u]) u=k; } used[u]=1; for(int k=1;k<=v;k++){ int VAL=FF[u][k]; if(!used[k]){ if(dis[u]+VAL<dis[k]){ dis[k]=dis[u] + VAL; } } } } for(int j=1;j<=v;j++) f[i][j]=dis[j]; } } dl dlmin(dl x,dl y){ return (y-x)>0.00000001?x:y; } void dp__(){ for(int i=0;i<MAXN;i++){ F[i][0]=2000000000.0; F[i][1]=2000000000.0; G[i][0]=2000000000.0; G[i][1]=2000000000.0; } F[0][0]=0; F[1][1]=0; for(int i=2;i<=n;i++){ for(int j=0;j<=m;j++){ dl casex,casey; casex=(dl)F[j][0]+f[c[i-1]][c[i]]; casey=(dl)F[j][1]+k[i-1]*f[d[i-1]][c[i]]+(1-k[i-1])*f[c[i-1]][c[i]]; G[j][0]=dlmin(casey,casex); if(j!=0){ casex=(dl)F[j-1][1]+(1-k[i-1])*(1-k[i])*f[c[i-1]][c[i]]+k[i-1]*(1-k[i])*f[d[i-1]][c[i]]+(1-k[i-1])*k[i]*f[c[i-1]][d[i]]+k[i-1]*k[i]*f[d[i-1]][d[i]]; casey=(dl)F[j-1][0]+(1-k[i])*f[c[i-1]][c[i]]+k[i]*f[c[i-1]][d[i]]; G[j][1]=dlmin(casey,casex); } } for(int j=0;j<=m;j++) F[j][0]=G[j][0],F[j][1]=G[j][1]; // for(int i=1;i<=m;i++){ // cout<<F[i][0]<<" "<<F[i][1]<<endl; // } // cout<<"********"<<endl; } dl ans=2147483647.00; for(int i=0;i<=m;i++){ // cout<<F[i][0]<<" "<<F[i][1]<<endl; ans=dlmin(ans,F[i][0]); ans=dlmin(ans,F[i][1]); } printf("%.2lf\n",ans); } void addege(int x,int y,int z){ cnt++; tal[cnt]=y; val[cnt]=z; nxt[cnt]=hed[x]; hed[x]=cnt; } int main(){ memset(FF,127,sizeof(FF)); //freopen("a.in","r",stdin); //cout<<"**"<<endl; scanf("%d%d%d%d",&n,&m,&v,&e); for(int i=1;i<=n;i++) scanf("%d",&c[i]); for(int i=1;i<=n;i++) scanf("%d",&d[i]); for(int i=1;i<=n;i++) scanf("%lf",&k[i]); for(int i=1;i<=e;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(x==y) continue; FF[x][y]=min(FF[x][y],z); FF[y][x]=min(FF[y][x],z); } //cout<<"&&"<<endl; dijkstra(); //cout<<"*"<<endl; dp__(); return 0; }