• HDU 4370


    题意:给一个N*N的矩阵C,和一个N*N的只由0和1组成的矩阵X。

       X满足以下条件:

       1.X 12+X 13+...X 1n=1 
       2.X 1n+X 2n+...X n-1n=1 
       3.任意 i (1<i<n), 都有 ∑X ki (1<=k<=n)=∑X ij (1<=j<=n). 

    求∑C ij*X ij(1<=i,j<=n) 的最小值(1<n<=300)。

    分析:乍一看也想不到这是道最短路的题。但将模型转换后,则易想到方法。根据01矩阵X满足的条件,可将其转化为一张图,其满足条件为:点1的出度为1;点N的入度为1;任意点v(1<v<n)的入度等于出度。再用矩阵C视作边权,Cij即边 (i,j)的权值,建图。

       所求的答案是min(1->N最短路的值,或由点1出发的环加上由点N出发的环的值)。用SPFA分别对点1、点N跑两次最短路。结果即min(d[N],cir[1]+cir[N])。

     

        #include<bits/stdc++.h>
        using namespace std;
        const int INF = 0x3f3f3f3f;
        const int maxn = 305;
    
        struct Spfa{
            int N;
            int G[maxn][maxn];
            int d[maxn];
            bool vis[maxn];
    
            void init(int N){ this->N=N;}
    
            void spfa(int s){
                memset(vis,0,sizeof(vis));
                queue<int> Q;
                for(int i=1;i<=N;++i){
                    d[i]=G[s][i];
                    if(i!=s){
                        Q.push(i);
                        vis[i]= true;
                    }
                }
                d[s]=INF;
                while(!Q.empty()){
                    int x =Q.front();Q.pop();
                    vis[x] = false;
                    for(int i =1;i<=N;++i){
                        if(x==i) continue;
                        if(d[i]>d[x]+G[x][i]){
                            d[i]=d[x]+G[x][i];
                            if(!vis[i]){
                                Q.push(i);
                                vis[i]=true;
                            }
                        }
                    }    
                }
            }
        }G;
    
    
        #define LOCAL
        int main()
        {
            #ifdef LOCAL
                freopen("in.txt","r",stdin);
                freopen("out.txt","w",stdout);
            #endif
            int N,M,s,t,u,v,T,tmp;
            while(~scanf("%d",&N)){
                if(!N) break;
                G.init(N);
                for(int i =1;i<=N;++i){
                    for(int j=1;j<=N;++j){
                        scanf("%d",&G.G[i][j]);
                    }
                }
                G.spfa(1);
                int res=G.d[N];
                int cir1=G.d[1];
                G.spfa(N);
                int cir2 = G.d[N];
                res=min(res,cir1+cir2);
                printf("%d
    ",res);
            }
            return 0;
        }
    为了更好的明天
  • 相关阅读:
    解决Tomcat9打印台乱码问题
    分治思想与归并排序
    linux下libuv库安装教程
    Linux init
    栈和堆上的内存分配和回收
    Python帮助文档中Iteration iterator iterable 的理解
    Qt基本框架介绍
    PyQt5+Python3.5.2-32bit开发环境搭建
    常用网站
    [Repost]Events and Signals in PyQt4
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9332268.html
Copyright © 2020-2023  润新知