• (中等) 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
  • 相关阅读:
    string的erase函数和find、find_first_of函数
    strtok和strtok_r
    Linux添加硬盘 挂载硬盘(附 Linux磁盘挂载和mount共享 带图)
    linux下访问中文目录文件
    用yield写协程实现生产者消费者
    用进程池和线程池实现高并发服务器
    python自带线程池
    python自带进程池
    模拟线程池代码
    面向对象的多次调用线程(含参版)
  • 原文地址:https://www.cnblogs.com/whywhy/p/4337893.html
Copyright © 2020-2023  润新知