Time Limit: 6000/2000MS (Java/Others)
Memory Limit: 65535/65535KB (Java/Others)
在UESTC,你会学到众多的 FT ,像 DFT , CTFT , DTFT , FFT 等,但是,这里,我们考虑一种名叫 CFT 的东西,它的作用与前面的不太一样,在这里,是将一个01串,映射为另一个等长的01串。
CFT:S1−>S2 ,( S1,S2 为 01 串)
CFT 的映射规则有m条,在下面给出;同时,每计算一个 CFT 需要一定的时间t,现在给你初始的01串S0,其长度为n,并且元素全为0,即00…0,问你,至少需要多长的时间,可以通过CFT将S0变为S1,S1长度也为n,且元素全为1(即11…1)
Input
首行两个整数
n,m(1≤n≤20,1≤m≤100000)
.
接下来m行,每行包括两个01串(长度为n)和一个整数
si,wi,ti,(1≤ti≤1000000000)
,表示
si
经过
CFT
变为
wi
需要
ti
的时间
Output
如果不能得到S1,输出-1;
否则输出将S0经过CFT变为S1所需最少时间。
Sample Input
3 5
000 110 2
000 010 4
000 101 2
110 111 1
000 111 3
Sample Output
3
Source
2017 UESTC Training for Graph Theory
题解:很显然的最短路….就是对于每一条映射连单向边就行。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
#define LiangJiaJun main
#define MAXN 1<<20
#define INF 1000000000LL * 100000LL + 4
#define ll long long
#define pa pair<ll,int>
using namespace std;
int n,m,ne,h[MAXN];
ll dis[MAXN];
bool vis[MAXN];
priority_queue<pa,vector<pa>,greater<pa> >q;
int trans(char *s,int l){
int T=0;
for(int i=1;i<=l;i++){
T<<=1;
if(s[i]=='1')T++;
}
return T;
}
struct edge{
int to , nt;
ll w;
}e[100004];
void add(int u,int v,ll w){
e[++ne].to = v;e[ne].w = w;
e[ne].nt = h[u];h[u] = ne;
}
ll dijkstra(int s,int t){
for(int i=0;i<=(1<<n)-1;i++)dis[i]=INF;
memset(vis,0,sizeof(vis));
dis[s]=0;q.push(make_pair(0,s));
while(!q.empty()){
int x = q.top().second;q.pop();
if(vis[x])continue;vis[x]=1;
for(int i=h[x];i;i=e[i].nt){
if( dis[e[i].to] > dis[x] + e[i].w){
dis[e[i].to] = dis[x] + e[i].w;
q.push(make_pair(dis[e[i].to],e[i].to));
}
}
}
if(dis[t]==INF)return -1;
return dis[t];
}
int LiangJiaJun(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
ll t;char x[24],y[24];
scanf("%s%s%lld",x+1,y+1,&t);
add(trans(x,n),trans(y,n),t);
}
printf("%lld\n",dijkstra(0,(1<<n)-1));
return 0;
}