zoukankan      html  css  js  c++  java
  • 【最短路】【spfa】CDOJ1647 酌贪泉而觉爽, 处涸辙以犹欢。

    题意: 给你一个全为0的01串,问你能否通过一系列的变换,得到全为1的01串。 分析: 将每个01串看作一个点,每一个变换可以看作是一条有向边,现在问题可以转化 为找从“00..0”这个点到“11..1”这个点的最短路,那么可以使用spfa来解决这个问题。 对于每个CFT,建一条有向边,从si指向ti,权值为ti。然后跑spfa即可。

    #include<cstdio>
    #include<queue>
    #include<iostream>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    queue<int>q;
    int n,m,__next[100010],v[100010],e,first[(1<<20)+10],w[100010];
    ll dis[(1<<20)+10];
    bool inq[(1<<20)+10];
    int trans(char T[]){
    	int len=strlen(T);
    	int res=0;
    	for(int i=0;i<len;++i){
    		res=res*2+T[i]-'0';
    	}
    	return res;
    }
    void AddEdge(int U,int V,int W){
    	v[++e]=V;
    	w[e]=W;
    	__next[e]=first[U];
    	first[U]=e;
    }
    void spfa(int s)
    {
        memset(dis+1,0x7f,sizeof(dis));
        q.push(s); inq[s]=1; dis[s]=0;
        while(!q.empty())
          {
            int U=q.front();
            for(int i=first[U];i;i=__next[i])
              if(dis[v[i]]>dis[U]+(ll)w[i])
                {
                  dis[v[i]]=dis[U]+(ll)w[i];
                  if(!inq[v[i]])
                    {
                      q.push(v[i]);
                      inq[v[i]]=1;
                    }
                }
            q.pop(); inq[U]=0;
          }
    }
    int main(){
    //	freopen("k.in","r",stdin);
    	int x,y,z;
    	char s[30];
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;++i){
    		scanf("%s",s);
    		x=trans(s);
    		scanf("%s%d",s,&z);
    		y=trans(s);
    		AddEdge(x,y,z);
    	}
    	spfa(0);
    	cout<<(dis[(1<<n)-1] < 100000000000001ll ? dis[(1<<n)-1] : -1)<<endl;
    	return 0;
    }
  • 相关阅读:
    如何在谷歌浏览器增加插件
    电脑更换硬盘
    电脑增加内存条
    了解计算机存储器
    Vue ----------- 了解, 展示json 数据
    JSON -------- json与字符串之间的转换
    JSON ------ 创建与访问
    Chartjs 简单使用 ------ 制作sin cos 折线图
    WebStorm ------------ 调整字体大小和背景
    输出正整数的各位数字
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6910410.html
Copyright © 2011-2022 走看看