zoukankan      html  css  js  c++  java
  • Gym

      给一个有向图,然后一些点有铁一些点有煤,然后问你从1走,至少花费多少(走一个没走过的点花费1,走过的点再走一次是不用花费的)可以拿到一个铁一个煤,点可以重复走。

      枚举从1节点到一个铁一个煤的交叉点即可,三遍bfs处理出dis[1,2,3][i]分别表示1号点到i的最小花费,i到铁的最小花费,i到煤的最小花费。

    #include<bits/stdc++.h>
    using namespace std;
    #define ls rt<<1
    #define rs (rt<<1)+1
    #define PI acos(-1)
    #define eps 1e-8
    #define ll long long
    #define fuck(x) cout<<#x<<"     "<<x<<endl;
    typedef pair<int,int> pii;
    const int inf=1e8;
    const int maxn=1e5+10;
    int d[4][2]={1,0,-1,0,0,1,0,-1};
    //int lowbit(int x){return x&-x;}
    //void add(int x,int v){while(x<=n)bit[x]+=v,x+=lowbit(x);}
    //int sum(int x){int ans=0;while(x>=1) ans+=bit[x],x-=lowbit(x);return ans;}
    inline ll read() {
        ll s = 0,w = 1;
        char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') w = -1;
            ch = getchar();
        }
        while(isdigit(ch))
            s = s * 10 + ch - '0',ch = getchar();
        return s * w;
    }
    inline void write(ll x) {
        if(x < 0)
            putchar('-'), x = -x;
        if(x > 9)
            write(x / 10);
        putchar(x % 10 + '0');
    }
    int gcd(int x,int y){
        return y==0?x:gcd(y,x%y);
    }
    
    int dis[4][maxn],vis[maxn],n;
    vector<int>g[maxn],ng[maxn];
    
    
    void bfs1(){
        queue<int>q;
        while(!q.empty()) q.pop();
        for(int i=1;i<=n+5;i++) vis[i]=0;
        q.push(1);
        vis[1]=1;
        dis[1][1]=0;
        while(!q.empty()){
            int u=q.front(),v;q.pop();
            for(int i=0;i<g[u].size();i++){
                int v=g[u][i];
                if(vis[v]) continue;
                vis[v]=1;
                dis[1][v]=dis[1][u]+1;
                q.push(v);
            }
        }
    }
    void bfs2(){
        queue<int>q;
        while(!q.empty()) q.pop();
        for(int i=1;i<=n+5;i++) vis[i]=0;
        q.push(n+1);
        vis[n+1]=1;
        dis[2][n+1]=0;
        while(!q.empty()){
            int u=q.front(),v;q.pop();
            for(int i=0;i<ng[u].size();i++){
                int v=ng[u][i];
                if(vis[v]) continue;
                if(u==n+1)
                    dis[2][v]=dis[2][n+1];
                else
                    dis[2][v]=dis[2][u]+1;
                vis[v]=1;
                q.push(v);
            }
        }
    }
    void bfs3(){
        queue<int>q;
        while(!q.empty()) q.pop();
        for(int i=1;i<=n+5;i++) vis[i]=0;
        q.push(n+2);
        vis[n+2]=1;
        dis[3][n+2]=0;
        while(!q.empty()){
            int u=q.front(),v;q.pop();
            for(int i=0;i<ng[u].size();i++){
                int v=ng[u][i];
                if(vis[v]) continue;
                if(u==n+2)
                    dis[3][v]=dis[3][n+2];
                else
                    dis[3][v]=dis[3][u]+1;
                vis[v]=1;
                q.push(v);
            }
        }
    }
    int main(){
        int m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++){
            dis[1][i]=dis[2][i]=dis[3][i]=inf;
        }
        for(int i=1;i<=m;i++)
        {
            int tmp;
            scanf("%d",&tmp);
            ng[n+1].push_back(tmp);
        }
        for(int i=1;i<=k;i++)
        {
            int tmp;
            scanf("%d",&tmp);
            ng[n+2].push_back(tmp);
        }
        for(int i=1;i<=n;i++){
            int tmp,v;
            scanf("%d",&tmp);
            while(tmp--){
                scanf("%d",&v);
                g[i].push_back(v);
                ng[v].push_back(i);
            }
        }
       // fuck(333);
        bfs1();
        bfs2();
        bfs3();
        int ans=inf;
       // fuck(233);
        for(int i=1;i<=n;i++){
            //cout<<dis[1][i]<<"  "<<dis[2][i]<<"  "<<dis[3][i]<<"  "<<endl;
            ans=min(ans,dis[1][i]+dis[2][i]+dis[3][i]);
        }
        if(ans==inf)
            puts("impossible");
        else
            write(ans),puts("");
        return 0;
    }
  • 相关阅读:
    代码管理模型概况
    循环链表
    队列

    链表
    java 2020-10-12T11:22:49.000+0800 字符串转换成正常时间格式
    动态数组
    mysql练习
    复杂度与LeetCode
    记一次带逗号的数字类型处理
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754682.html
Copyright © 2011-2022 走看看