思路:题干太长,而且很简单,这就不说了。。
思路:本来想着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; }
原文地址:http://blog.csdn.net/jiangyuze831/article/details/42677889