zoukankan      html  css  js  c++  java
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。

      Description

      Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij (1<=i,j<=n),which is 0 or 1.

      Besides,X ij meets the following conditions:

    1.X 12+X 13+...X 1n=1
    2.X 1n+X 2n+...X n-1n=1
    3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n).

      For example, if n=4,we can get the following equality:

    X 12+X 13+X 14=1
    X 14+X 24+X 34=1
    X 12+X 22+X 32+X 42=X 21+X 22+X 23+X 24
    X 13+X 23+X 33+X 43=X 31+X 32+X 33+X 34

      Now ,we want to know the minimum of ∑C ij*X ij(1<=i,j<=n) you can get.

      神题,可以转化为最短路问题。这个题可以一点一点的分析,首先就是选了第一行的第k个之后,就要选一个第k行的,所以建边 1->k 边权为第一行第k个的值,然后求1->n的最短路就好。。。。。。

      不过这里还有一种特殊情况,就是1和其他形成一个环,N和其他形成一个环。所以答案就是两个环的和,和最短路中小的那一个。。。

    代码如下:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
        
    using namespace std;
    
    const int MaxN=400;
    const int INF=10e8;
    
    void Dijkstra(int cost[][MaxN],int lowcost[],int N,int start)
    {
        priority_queue <int> que;
        int t;
    
        for(int i=1;i<=N;++i)
            lowcost[i]=INF;
    
        que.push(start);
    
        while(!que.empty())
        {
            t=que.top();
            que.pop();
    
            for(int i=1;i<=N;++i)
                if(i!=t)
                    if(lowcost[t]==INF || lowcost[i]>lowcost[t]+cost[t][i])
                    {
                        lowcost[i]=(lowcost[t]==INF ? 0 : lowcost[t])+cost[t][i];
                        que.push(i);
                    }
        }
    }
    
    int map1[MaxN][MaxN];
    int ans[MaxN];
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
    
        int N;
        int t1,t2;
    
        while(~scanf("%d",&N))
        {
            for(int i=1;i<=N;++i)
                for(int j=1;j<=N;++j)
                    scanf("%d",&map1[i][j]);
    
            Dijkstra(map1,ans,N,1);
            t1=ans[N];
            t2=ans[1];
    
            Dijkstra(map1,ans,N,N);
            t2+=ans[N];
    
            printf("%d
    ",min(t1,t2));
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/whywhy/p/4337893.html
Copyright © 2011-2022 走看看