首页 > 代码库 > BZOJ 3045 电话线路 暴力

BZOJ 3045 电话线路 暴力

思路:题干太长,而且很简单,这就不说了。。


思路:本来想着T了就写后缀数组,或者加堆优化什么的,结果直接就A了。。


CODE:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 50010
#define MAXE 5000010
#define BASE 2333
#define INF 0x3f3f3f3f
using namespace std;
 
unsigned long long power[20];
 
struct Complex{
    char s[12];
    int _id,num[10];
    unsigned long long hash,_hash,sorting;
     
    bool operator <(const Complex &a)const {
        return sorting < a.sorting;
    }
    void Read(int p) {
        _id = p;
        scanf("%s",s + 1);
        hash = _hash = 0;
        for(int i = 1; i <= 10; ++i) {
            hash = hash * BASE + s[i];
            ++num[s[i] - '0'];
        }
        for(int i = 0; i <= 9; ++i)
            _hash = _hash * BASE + num[i];
    }
    int LCP(const Complex &a)const {
        for(int i = 1;; ++i)
            if(s[i] != a.s[i])
                return i - 1;
        return 0;
    }   
}src[MAX];
 
int cnt;
int cost[10];
 
void Pretreatment()
{
    power[0] = 1;
    for(int i = 1; i <= 15; ++i)
        power[i] = power[i - 1] * BASE;
}
 
int head[MAX],total;
int next[MAXE],aim[MAXE],length[MAXE];
 
inline void Add(int x,int y,int len)
{
    next[++total] = head[x];
    aim[total] = y;
    length[total] = len;
    head[x] = total;
}
 
inline void AddEdge(int l,int r)
{
    for(int i = l; i <= r; ++i)
        for(int j = i + 1; j <= r; ++j) {
            int lcp = src[i].LCP(src[j]);
            Add(src[i]._id,src[j]._id,cost[lcp]);
            Add(src[j]._id,src[i]._id,cost[lcp]);
        }
}
 
inline void AddEdge(int l,int r,bool flag)
{
    for(int i = l; i <= r; ++i)
        for(int j = i + 1; j <= r; ++j)
            if(src[i]._hash == src[j]._hash) {
                int lcp = src[i].LCP(src[j]);
                Add(src[i]._id,src[j]._id,cost[lcp]);
                Add(src[j]._id,src[i]._id,cost[lcp]);
            }
}
 
int SPFA()
{
    static int f[MAX];
    static bool v[MAX];
    static queue<int> q;
    memset(f,0x3f,sizeof(f));
    f[1] = 0;
    q.push(1);
    while(!q.empty()) {
        int x = q.front(); q.pop();
        v[x] = false;
        for(int i = head[x]; i; i = next[i])
            if(f[aim[i]] > f[x] + length[i]) {
                f[aim[i]] = f[x] + length[i];
                if(!v[aim[i]]) {
                    v[aim[i]] = true;
                    q.push(aim[i]);
                }
            }
    }
    return f[cnt] == INF ? -1:f[cnt];
}
 
int main()
{
    Pretreatment();
    cin >> cnt;   
    for(int i = 0; i <= 9; ++i)
        scanf("%d",&cost[i]);
    for(int i = 1; i <= cnt; ++i)
        src[i].Read(i);
    for(int i = 1; i <= 10; ++i) {
        for(int j = 1; j <= cnt; ++j)
            src[j].sorting = src[j].hash - power[10 - i] * src[j].s[i];
        sort(src + 1,src + cnt + 1);
        unsigned long long now = src[1].sorting;
        int last = 1;
        for(int j = 1; j <= cnt; ++j)
            if(src[j].sorting != now) {
                AddEdge(last,j - 1);
                last = j;
                now = src[j].sorting;           
            }
        AddEdge(last,cnt);
    }
    for(int i = 1; i <= 10; ++i)
        for(int j = i + 1; j <= 10; ++j) {
            for(int k = 1; k <= cnt; ++k)
                src[k].sorting = src[k].hash - power[10 - i] * src[k].s[i] - power[10 - j] * src[k].s[j];
            sort(src + 1,src + cnt + 1);
            unsigned long long now = src[1].sorting;
            int last = 1;
            for(int k = 1; k <= cnt; ++k)
                if(src[k].sorting != now) {
                    AddEdge(last,k - 1,false);
                    last = k;
                    now = src[k].sorting;
                }
            AddEdge(last,cnt,false);
        }
    cout << SPFA() << endl;
    return 0;
}


BZOJ 3045 电话线路 暴力