• 【枚举】【SPFA】Urozero Autumn Training Camp 2016 Day 5: NWERC-2016 Problem I. Iron and Coal


    那个人派出的队伍的行走的路径一定前半程是重合的,后半程分叉开来。

    于是预处理每个点离1号点的最短路,到最近的铁的最短路,到最近的煤的最短路。(三次BFS / SPFA)然后枚举分岔点,尝试更新答案即可。

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    queue<int>q;
    int v[1000010],first[100010],next[1000010],en;
    ll ans=2147483647ll;
    void AddEdge(int U,int V){
    	v[++en]=V;
    	next[en]=first[U];
    	first[U]=en;
    }
    int n,m,K,a[100010],b[100010],dis1[100010],dis2[100010],dis3[100010],eu[1000010],ev[1000010],es;
    bool inq[100010];
    void spfa1(int dis[])
    {
    	memset(dis,0x7f,sizeof(int)*100010);
    	memset(inq,0,sizeof(inq));
    	for(int i=1;i<=m;++i){
    		dis[a[i]]=0;
    		q.push(a[i]);
    		inq[a[i]]=1;
    	}
        while(!q.empty())
          {
            int U=q.front();
            for(int i=first[U];i;i=next[i])
              if(dis[v[i]]>dis[U]+1)
                {
                  dis[v[i]]=dis[U]+1;
                  if(!inq[v[i]])
                    {
                      q.push(v[i]);
                      inq[v[i]]=1;
                    }
                }
            q.pop(); inq[U]=0;
          }
    }
    void spfa2(int dis[])
    {
    	memset(dis,0x7f,sizeof(int)*100010);
    	memset(inq,0,sizeof(inq));
    	for(int i=1;i<=K;++i){
    		dis[b[i]]=0;
    		q.push(b[i]);
    		inq[b[i]]=1;
    	}
        while(!q.empty())
          {
            int U=q.front();
            for(int i=first[U];i;i=next[i])
              if(dis[v[i]]>dis[U]+1)
                {
                  dis[v[i]]=dis[U]+1;
                  if(!inq[v[i]])
                    {
                      q.push(v[i]);
                      inq[v[i]]=1;
                    }
                }
            q.pop(); inq[U]=0;
          }
    }
    void spfa3(int dis[]){
    	memset(dis,0x7f,sizeof(int)*100010);
    	memset(inq,0,sizeof(inq));
    	dis[1]=0; q.push(1); inq[1]=1;
        while(!q.empty())
          {
            int U=q.front();
            for(int i=first[U];i;i=next[i])
              if(dis[v[i]]>dis[U]+1)
                {
                  dis[v[i]]=dis[U]+1;
                  if(!inq[v[i]])
                    {
                      q.push(v[i]);
                      inq[v[i]]=1;
                    }
                }
            q.pop(); inq[U]=0;
          }
    }
    int main(){
    //	freopen("i.in","r",stdin);
    	scanf("%d%d%d",&n,&m,&K);
    	for(int i=1;i<=m;++i){
    		scanf("%d",&a[i]);
    	}
    	for(int i=1;i<=K;++i){
    		scanf("%d",&b[i]);
    	}
    	int x,y;
    	for(int i=1;i<=n;++i){
    		scanf("%d",&x);
    		for(int j=1;j<=x;++j){
    			scanf("%d",&y);
    			AddEdge(y,i);
    			eu[++es]=i;
    			ev[es]=y;
    		}
    	}
    	spfa1(dis1);
    	spfa2(dis2);
    	memset(first,0,sizeof(first));
    	memset(next,0,sizeof(next));
    	memset(v,0,sizeof(v));
    	en=0;
    	for(int i=1;i<=es;++i){
    		AddEdge(eu[i],ev[i]);
    	}
    	spfa3(dis3);
    	for(int i=1;i<=n;++i){
    		ans=min(ans,(ll)dis3[i]+(ll)dis1[i]+(ll)dis2[i]);
    	}
    	if(ans<=2000000000ll){
    		printf("%d
    ",(int)ans);
    	}
    	else{
    		puts("impossible");
    	}
    	return 0;
    }
  • 相关阅读:
    log4c demo
    c连接redis
    1108. IP 地址无效化
    1295. 统计位数为偶数的数字
    LCP 1. 猜数字
    1281. 整数的各位积和之差
    1313. 解压缩编码列表
    仿射变换及其变换矩阵的理解
    RNN 与 LSTM 的原理详解
    网络深度对深度学习模型性能有什么影响?
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7198397.html
Copyright © 2020-2023  润新知