• poj 3164 Command Network


    Command Network

     POJ - 3164 

    题目大意:给出一个有向图,给出n个顶点的坐标,以及每条边连接的顶点,指定一个起点,找到一个方案,使得从这个点到其他所有点的路径的权值和最小,求最小权值

    /*
        最小树形图模板题
        对缩点及其下面几个部分的解释: 
        vis相当于一个bool数组,标记某个点是否被访问过,因为每一次的for都要用vis,每一次赋值i可以避免memset false,快
        pre记录环上前驱,缩点之后点的编号会有所改变,用col记录
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define maxn 110
    #define INF 2e9
    using namespace std;
    int n,m,pre[maxn],vis[maxn],col[maxn],num;
    struct node{
        int from,to;
        double v;
    }e[10010];
    double x[maxn],y[maxn],in[maxn];
    double zhuliu(){
        int tot=n,root=1,cirnum,to;
        double ans=0;
        while(1){
            for(int i=1;i<=tot;i++)in[i]=INF;
            for(int i=1;i<=m;i++)//枚举每条边 
                if(e[i].v<in[e[i].to]&&e[i].from!=e[i].to){
                    pre[e[i].to]=e[i].from;
                    in[e[i].to]=e[i].v;//in[i]表示指向i最小的边权 
                }
            for(int i=1;i<=tot;i++)//判断能否组成树形图 
                if(i!=root&&in[i]==INF)return -1;
            cirnum=0;
            memset(vis,0,sizeof(vis));
            memset(col,0,sizeof(col));
            in[root]=0;
            for(int i=1;i<=tot;i++){//缩点 
                ans+=in[i];
                to=i;
                while(vis[to]!=i&&!col[to]&&to!=root)
                {vis[to]=i;to=pre[to];}
                if(to!=root&&!col[to]){
                    cirnum++;
                    for(int j=pre[to];j!=to;j=pre[j])
                        col[j]=cirnum;
                    col[to]=cirnum;
                }
            }
            if(!cirnum)break;
            for(int i=1;i<=tot;i++)
                if(!col[i])col[i]=++cirnum;
            for(int i=1;i<=m;i++){
                to=e[i].to;
                e[i].from=col[e[i].from];
                e[i].to=col[e[i].to];
                if(e[i].from!=e[i].to)e[i].v-=in[to];
            }
            tot=cirnum;
            root=col[root];
        }
        return ans;
    }
    int main(){
        double ans;
        while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
            num=0;
            int a,b;
            for(int i=1;i<=m;i++){
                scanf("%d%d",&a,&b);
                double dis=sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
                if(a!=b){
                    e[++num].to=b;
                    e[num].from=a;
                    e[num].v=dis;
                }
            }
            m=num;
            ans=zhuliu();
            if(ans==-1)puts("poor snoopy");
            else printf("%.2lf
    ",ans);
        }
    }
  • 相关阅读:
    jsp九大内置对象和4个域对象
    小甜点
    response编码
    request请求编码处理
    防盗链模拟
    request浏览器判断
    request获取ip
    ServletConfig
    HttpServlet原理
    Servlet,GenericServlet,httpServlet区别
  • 原文地址:https://www.cnblogs.com/thmyl/p/8119580.html
Copyright © 2020-2023  润新知