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;
}
12-29 12:19