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;
    }
  • 相关阅读:
    hdu 1253
    poj 2531 Network Saboteur
    rwkj 1501 数据结构:图的DFS遍历
    rwkj 1306 素数========拓展
    nyist 91 阶乘之和
    nyist 65 另一种阶乘问题
    nyist 31 5个数求最值
    nyist 22 素数求和
    向量 vector
    字符串 统计 ,删除,连接,变换
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6910410.html
Copyright © 2011-2022 走看看