SRM573 Div1Medium Ski Resorts

這題有這麼一個思路:
將每個x 變成n 個點{x,y} 代表點x 現在的特徵值是y
然後對於每個Gi,j==Y
{i,a} 連向{j,b} 一條邊,a,b[1,n] 之間連一條邊,邊權爲|valbvalj|
最後再造兩個點
一個點向所有的點{1,x} 連邊,邊權爲|val[x]val[1]|
另一個由所有的點{n,x} 向它連邊,邊權爲0
最後跑一邊Dijkstra 就行了, 注意最終答案爲longlong 類型
代碼如下:

#include<bits/stdc++.h>
using namespace std;
#define M 55
#define ll long long
const ll oo=1e13;
void Min(ll &a,ll b){
    if(a>b)a=b;
}
char str[M];
int ok[M][M],val[M];
int dis[M][M][M][M];
struct node{
    int i,a;ll len;
    bool operator <(const node &A)const{
        return len>A.len;
    }
};
priority_queue<node>Q;
ll mark[M][M];int T[M][M];
int n;
ll Dijkstra(){//dp
    Q.push((node){0,0,0});
    while(!Q.empty()){
        node tmp=Q.top();Q.pop();
        if(tmp.i==n+1&&tmp.a==n+1)return tmp.len;
        if(T[tmp.i][tmp.a])continue;
        T[tmp.i][tmp.a]=1;
        for(int j=1;j<=n;j++)
            for(int b=1;b<=n;b++){
                ll len=tmp.len+dis[tmp.i][tmp.a][j][b];
                if(~dis[tmp.i][tmp.a][j][b]&&mark[j][b]>len){
                    mark[j][b]=len;
                    Q.push((node){j,b,len});
                }
            }
        ll len=tmp.len+dis[tmp.i][tmp.a][n+1][n+1];
        if(~dis[tmp.i][tmp.a][n+1][n+1]&&mark[n+1][n+1]>len)
            Q.push((node){n+1,n+1,tmp.len+dis[tmp.i][tmp.a][n+1][n+1]});
    }
    return -1;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",str+1);
        for(int j=1;j<=n;j++)
            if(str[j]=='Y')ok[i][j]=1;
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=n+1;j++)
            mark[i][j]=oo;
    memset(dis,-1,sizeof(dis));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int a=1;a<=n;a++)
                for(int b=1;b<=n;b++)
                    if(ok[i][j]&&val[a]>=val[b])dis[i][a][j][b]=abs(val[j]-val[b]);
    for(int i=1;i<=n;i++){
        dis[0][0][1][i]=dis[1][i][0][0]=abs(val[i]-val[1]);
        dis[n+1][n+1][n][i]=dis[n][i][n+1][n+1]=0;
    }
//預處理
    cout<<Dijkstra()<<endl;
    return 0;
}
發佈了58 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章