zoukankan      html  css  js  c++  java
  • HDU

    Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory problems everyday.
    The task is simple : ZKC will give Pan a directed graph every time, and selects some nodes from that graph, you can calculate the minimum distance of every pair of nodes chosen in these nodes and now ZKC only cares about the minimum among them. That is still too hard for poor Pan, so he asks you for help.

    InputThe first line contains one integer T, represents the number of Test Cases.1≤T≤5.Then T Test Cases, for each Test Cases, the first line contains two integers n,m representing the number of nodes and the number of edges.1≤n,m≤100000
    Then m lines follow. Each line contains three integers ,i  xi,yi representing an edge, and i  vi representing its length.1≤,i  xi,yi ≤n,1≤i  vi ≤100000
    Then one line contains one integer K, the number of nodes that Master Dong selects out.1≤K≤n
    The following line contains K unique integers i  ai , the nodes that Master Dong selects out.1≤i  ai ≤n,i  ai !=aj
    OutputFor every Test Case, output one integer: the answerSample Input

    1
    5 6
    1 2 1
    2 3 3
    3 1 3
    2 5 1
    2 4 2
    4 3 1
    3
    1 3 5

    Sample Output

    Case #1: 2

    题意:给定有向图,然后给一个集合,让你在这个集合选一个作为起点,一个作为终点,其最短路最小。

    思路:上次做过树上最大收益(边权为花费,顶点有价格,求最大差价),每个点连接汇点,权值为负价;每个点连接源点,权值为正价。然后跑最长路。

    此题也是一样的套路,但是起点和终点不能是同一点,所以我们需要分组。

    这里分组可以随机20次;也可以用“二进制分组法”。:

    举例说明,将1 2 3 4 进行分组,四个数的二进制形式为: 001 010 011 100
    第一次看第0位为1的数,那么A={1,3},B={2,4}
    第一次看第1位为1的数,那么A={2,3},B={1,4}
    第一次看第2位为1的数,那么A={4},B={1,2,3}
    可以看出,任意一对数字,都至少有一次机会不在同一组中。

    由于是有向图,还得反过来来一次。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define ll long long
    using namespace std;
    const ll inf=1234567645893456783;
    const int maxn=100010;
    int S,T,Laxt[maxn],Next[maxn];
    int in[maxn],To[maxn],Len[maxn],a[maxn],cnt;
    ll dis[maxn],ans;
    vector<int>G[maxn];
    void add(int u,int v,int w){
        Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=w;
    }
    void SPFA()
    {
        rep(i,S,T) dis[i]=inf,in[i]=0;
        dis[S]=0; queue<int>q;
        q.push(S); in[S]=1;
        while(!q.empty()){
            int u=q.front(); q.pop();
            for(int i=Laxt[u];i;i=Next[i]){
                int v=To[i]; if(dis[u]+Len[i]<dis[v]) {
                    dis[v]=dis[u]+Len[i];
                    if(!in[v]) in[v]=1,q.push(v);
                }
            }
            for(int i=0;i<G[u].size();i++){
                int v=G[u][i]; if(dis[u]<dis[v]) {
                    dis[v]=dis[u];
                    if(!in[v]) in[v]=1,q.push(v);
                }
            }
            in[u]=0;
        }
        ans=min(ans,dis[T]);
    }
    int main()
    {
        int C,Cas=0,N,M,tot,u,v,w;
        scanf("%d",&C);
        while(C--){
            scanf("%d%d",&N,&M); T=N+1; ans=inf;
            rep(j,S,T) Laxt[j]=0; cnt=0;
            rep(i,1,M) scanf("%d%d%d",&u,&v,&w),add(u,v,w);
            scanf("%d",&tot);
            rep(i,1,tot) scanf("%d",&a[i]);
            rep(i,0,17){
                rep(j,S,T) G[j].clear();
                rep(j,1,tot)
                  if(j&(1<<i)) G[S].push_back(a[j]);
                  else G[a[j]].push_back(T);
                SPFA();
                rep(j,S,T) G[j].clear();
                rep(j,1,tot)
                  if(j&(1<<i)) G[a[j]].push_back(T);
                  else G[S].push_back(a[j]);
                SPFA();
            }
            printf("Case #%d: %lld
    ",++Cas,ans);
        }
        return 0;
    }
  • 相关阅读:
    Linux 清理boot分区
    Linux 虚拟内存
    使用mongoskin操作MongoDB
    nodejs操作session和cookie
    nodejs接收get参数和post参数
    Tomcat--在IDEA创建Java Web项目,通过tomcat启动
    Tomcat--配置
    Mac安装Tomcat
    XML--解析
    XML--约束
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9824108.html
Copyright © 2011-2022 走看看