zoukankan      html  css  js  c++  java
  • 文化之旅

    传送门

    ovo这题没有靠谱的多项式复杂度的做法?!

    好吧我也不知道该怎么做,于是学了一个大佬的Floyd玄学算法。

    具体的实现还是很简单的,就是每次使用Floyd更新,必须要满足以下情况:

    1.当前三个点文化不互相排斥

    2.通往k(用于更新的点)的道路上所经过的文化与当前文化不互相排斥

    3.距离更小

    注意使用g[i][j][k]表示从i到j的路上排斥k文化,每次在更新的时候使用按位或来更新。

    这样就可以做了……orz

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<queue>
    #include<set>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 50005;
    const int INF = 10000000;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    int n,k,m,s,t,c[105],a[105][105],dis[105][105],u,v,d;
    bool g[105][105][105];
    
    void floyd()
    {
        rep(k,1,n)
        rep(i,1,n)
        rep(j,1,n)
        {
        if(a[c[k]][c[i]] || a[c[j]][c[k]]) continue;//不符合第一种情况
        if(g[i][k][c[j]] || g[k][j][c[i]]) continue;//不符合第二种情况(注意这里不要把开始城市和结束城市搞混)
        if(dis[i][k] + dis[k][j] < dis[i][j])
        {
            rep(t,1,n) g[i][j][t] = g[i][k][t] | g[k][j][t];//枚举每一种文化并且进行更新
            g[i][j][c[k]] = 1;
            dis[i][j] = dis[i][k] + dis[k][j];//更新距离
        }
        }
    }
    
    int main()
    {
        n = read(),k = read(),m = read(),s = read(),t = read();
        rep(i,1,n)
        rep(j,1,n) dis[i][j] = INF;
        rep(i,1,n) c[i] = read(),dis[i][i] = 0;
        rep(i,1,k)
        rep(j,1,k) a[i][j] = read();
        rep(i,1,m)
        {
        u = read(),v = read(),d = read();
        if(!a[c[v]][c[u]] && c[u] != c[v]) dis[u][v] = min(dis[u][v],d);
        if(!a[c[u]][c[v]] && c[u] != c[v]) dis[v][u] = min(dis[v][u],d);//只有在符合条件的时候才更新距离
        }
        rep(i,1,n)
        rep(j,1,n) g[i][j][c[i]] = 1,g[i][j][c[j]] = 1;//设置路径上的文化排斥
        floyd();
        if(dis[s][t] == INF) printf("-1
    ");
        else printf("%d
    ",dis[s][t]);
        return 0;
    }
  • 相关阅读:
    css选择器学习(二)属性选择器
    css选择器学习(一)
    css引用优先级
    canvas制图学习
    cookie,localStorage,sessionStorage
    HTTP协议中get和post的区别
    台灯发展史
    Object类实现的方法
    react学习网站
    什么是接口测试,接口测试的目的,如何进行接口测试
  • 原文地址:https://www.cnblogs.com/captain1/p/9604962.html
Copyright © 2011-2022 走看看