• HDU


    HDU - 4370 题目链接

    我看到这道题的时候就是一脸懵,这能用最短路求解???

    解题方法

    条件

    1.X12+X13+...X1n=1
    2.X1n+X2n+...Xn-1n=1
    3.for each i (1<i<n), satisfies ∑Xki (1<=k<=n)=∑Xij (1<=j<=n).

    题意理解

    • 对于第一条我们可以理解为,点1只能出去一次,也就是点1的出度为1。
    • 对于第二条我们可以理解为,点n只能进来一次,也就是点n的入度为1。
    • 对于第三条我们可以理解为,点(1,n)的出度和入度相等并且都是1。

    而这道题目的意思就是求解经过点1,和点n的最短路,显然我们有两种情况。
    一、一条直线从1 -> n。
    二、以点1形成一个环,以点n形成一个环。
    答案就是上述两种情况的最小值。

    代码

    //Powered by CK 2020:04:08
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int N = 310;
    int maze[N][N], visit[N], dis[N], n;
    void spfa(int rt) {
    	queue<int> q;
    	for(int i = 1;  i <= n; i++) {
    		if(i != rt) {//因为可能是求环问题,我们把起始点设置为无穷大。
    			visit[i] = 1;
    			dis[i] = maze[rt][i];
    			q.push(i);
    		}
    		else {
    			dis[i] = INF;
    			visit[i] = 0;
    		}
    	}
    	while(!q.empty()) {//spfa的基本步骤。
    		int temp = q.front();
    		q.pop();
    		visit[temp] = 0;
    		for(int i = 1; i <= n; i++) {
    			if(dis[i] > dis[temp] + maze[temp][i]) {
    				dis[i] = dis[temp] + maze[temp][i];
    				if(!visit[i]) {
    					visit[i] = 1;
    					q.push(i);
    				}
    			}
    		}
    	}
    } 
    int main() {
    	// freopen("in.txt", "r", stdin);
    	while(scanf("%d", &n) != EOF) {
    		for(int i = 1; i <= n; i++)
    			for(int j = 1; j <= n; j++)
    				scanf("%d", &maze[i][j]);
    		spfa(1);
    		int len = dis[n];//从1 -> n 的最短路
    		int cicle = dis[1];//以点1形成的环
    		spfa(n);
    		cicle += dis[n];//加上以点n形成的环
    		printf("%d
    ", min(len, cicle));//取最小值
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    bug的约束
    bug管理规范
    FTP小教程
    测试需求,产品需求,项目需求
    如何理解客户需求、市场需求、产品需求、业务需求、特性、功能需求 ?(转)
    什么是测试需求?(转)
    绑定与非绑定,反射,内置方法
    面向对象之组合、封装、多态、property装饰器
    面向对象之继承与派生,属性查找
    面向对象基础
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12660284.html
Copyright © 2020-2023  润新知