[UESTC1647]酌贪泉而觉爽, 处涸辙以犹欢。

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(1n20,1m100000) .
接下来m行,每行包括两个01串(长度为n)和一个整数 si,wi,ti,(1ti1000000000) ,表示 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值