HDOJ 5294 Tricks Device 最短路(记录路径)+最小割

最短路记录路径,同时求出最短的路径上最少要有多少条边,

然后用在最短路上的边重新构图后求最小割.

Tricks Device

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1584    Accepted Submission(s): 388

Problem Description

Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu’s at the entrance of the tomb while Dumb Zhang’s at the end of it. The tomb is made up of many chambers, the total number is N. And there are M channels connecting the chambers. Innocent Wu wants
to catch up Dumb Zhang to find out the answers of some questions, however, it’s Dumb Zhang’s intention to keep Innocent Wu in the dark, to do which he has to stop Innocent Wu from getting him. Only via the original shortest ways from the entrance to the end
of the tomb costs the minimum time, and that’s the only chance Innocent Wu can catch Dumb Zhang.

Unfortunately, Dumb Zhang masters the art of becoming invisible(奇门遁甲) and tricks devices of this tomb, he can cut off the connections between chambers by using them. Dumb Zhang wanders how many channels at least he has to cut to stop Innocent Wu. And Innocent
Wu wants to know after how many channels at most Dumb Zhang cut off Innocent Wu still has the chance to catch Dumb Zhang.

Input

There are multiple test cases. Please process till EOF.

For each case,the first line must includes two integers, N(<=2000), M(<=60000). N is the total number of the chambers, M is the total number of the channels.

In the following M lines, every line must includes three numbers, and use ai、bi、li as channel i connecting chamber ai and bi(1<=ai,bi<=n), it costs li(0<li<=100) minute to pass channel i.

The entrance of the tomb is at the chamber one, the end of tomb is at the chamber N.

Output

Output two numbers to stand for the answers of Dumb Zhang and Innocent Wu’s questions.

Sample Input

8 9
1 2 2
2 3 2
2 4 1
3 5 3
4 5 4
5 8 1
1 6 2
6 7 5
7 8 1

Sample Output

2 6

Author

FZUACM

Source

2015 Multi-University Training Contest 1

/* ***********************************************
Author        :CKboss
Created Time  :2015年07月24日 星期五 10时07分09秒
File Name     :HDOJ5294.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef pair<int,int> pII;

const int INF=0x3f3f3f3f;
const int maxn=2200;

int n,m;

/*************EDGE********************/

struct Edge
{
	int to,next,cost,cap,flow;
}edge[maxn*60],edge2[maxn*60];

int Adj[maxn],Size;
int Adj2[maxn],Size2;

void Add_Edge(int u,int v,int c)
{
	edge[Size].to=v;
	edge[Size].next=Adj[u];
	edge[Size].cost=c;
	Adj[u]=Size++;
}

/********spfa************/

int dist[maxn];
bool inQ[maxn];

vector<int> Pre[maxn];

int spfa(Edge* edge,int* Adj)
{
    memset(dist,63,sizeof(dist));
    memset(inQ,false,sizeof(inQ));
    dist[1]=0;
    queue<int> q;
    inQ[1]=true;q.push(1);

    while(!q.empty())
    {
        int u=q.front();q.pop();

        for(int i=Adj[u];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dist[v]>dist[u]+edge[i].cost)
            {
				Pre[v].clear();
				Pre[v].push_back(u);

                dist[v]=dist[u]+edge[i].cost;

                if(!inQ[v])
                {
                    inQ[v]=true;
                    q.push(v);
                }
            }
			else if(dist[v]==dist[u]+edge[i].cost)
			{
				Pre[v].push_back(u);
			}
        }

        inQ[u]=false;

    }
    return dist[n];
}

/********************rebuild************************/

void Add_Edge2(int u,int v,int w,int rw=0)
{
	edge2[Size2].cost=1;
	edge2[Size2].to=v; edge2[Size2].cap=w; edge2[Size2].next=Adj2[u];
	edge2[Size2].flow=0; Adj2[u]=Size2++;

	edge2[Size2].cost=1;
	edge2[Size2].to=u; edge2[Size2].cap=w; edge2[Size2].next=Adj2[v];
	edge2[Size2].flow=0; Adj2[v]=Size2++;
}

bool used[maxn];
int edges;

void rebuild()
{
	memset(used,false,sizeof(used));
	queue<int> q;
	q.push(n); used[n]=true;
	edges=0;

	while(!q.empty())
	{
		int v=q.front(); q.pop();
		for(int i=0,sz=Pre[v].size();i<sz;i++)
		{
			int u=Pre[v][i];
			/// u--->v
			//cout<<u<<" ---> "<<v<<endl;
			edges++;
			Add_Edge2(u,v,1);

			if(used[u]==false)
			{
				used[u]=true; q.push(u);
			}
		}
	}
}

/************************max_flow*******************************/

int gap[maxn],dep[maxn],pre[maxn],cur[maxn];

int sap(int start,int end,int N,Edge* edge=edge2)
{
	memset(gap,0,sizeof(gap));
	memset(dep,0,sizeof(dep));
	memcpy(cur,Adj2,sizeof(Adj2));

	int u=start;
	pre[u]=-1; gap[0]=N;
	int ans=0;

	while(dep[start]<N)
	{
		if(u==end)
		{
			int Min=INF;
			for(int i=pre[u];~i;i=pre[edge[i^1].to])
			{
				if(Min>edge[i].cap-edge[i].flow)
					Min=edge[i].cap-edge[i].flow;
			}
			for(int i=pre[u];~i;i=pre[edge[i^1].to])
			{
				edge[i].flow+=Min;
				edge[i^1].flow-=Min;
			}
			u=start;
			ans+=Min;
			continue;
		}

		bool flag=false;
		int v;
		for(int i=cur[u];~i;i=edge[i].next)
		{
			v=edge[i].to;
			if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
			{
				flag=true;
				cur[u]=pre[v]=i;
				break;
			}
		}

		if(flag)
		{
			u=v; continue;
		}

		int Min=N;
		for(int i=Adj2[u];~i;i=edge[i].next)
		{
			if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
			{
				Min=dep[edge[i].to];
				cur[u]=i;
			}
		}
		gap[dep[u]]--;
		if(!gap[dep[u]]) return ans;
		dep[u]=Min+1;
		gap[dep[u]]++;
		if(u!=start) u=edge[pre[u]^1].to;
	}

	return ans;
}

void init()
{
	memset(Adj,-1,sizeof(Adj)); Size=0;
	memset(Adj2,-1,sizeof(Adj2)); Size2=0;
	for(int i=1;i<=n;i++) Pre[i].clear();
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	while(scanf("%d%d",&n,&m)!=EOF)
	{
		init();
		for(int i=0,u,v,c;i<m;i++)
		{
			scanf("%d%d%d",&u,&v,&c);
			Add_Edge(u,v,c); Add_Edge(v,u,c);
		}
		spfa(edge,Adj);
		rebuild();
		int max_flow=sap(1,n,n);
		int min_short_path=spfa(edge2,Adj2);
		printf("%d %d\n",max_flow,m-min_short_path);
	}

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 08:27:39

HDOJ 5294 Tricks Device 最短路(记录路径)+最小割的相关文章

hdu 5294 Tricks Device 最短路建图+最小割

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 375    Accepted Submission(s): 98 Problem Description Innocent Wu follows Dumb Zh

HDU 5294 Tricks Device (最大流+最短路)

题目链接:HDU 5294 Tricks Device 题意:n个点,m条边,并且一个人从1走到n只会走1到n的最短路径,问至少破坏几条边使原图的最短路不存在,最多破坏几条边使原图的最短路劲仍存在 思路: 1.跑一遍最短路,记录下所有最短路径,将这些最短路径的边以(0,1)(流量,容量)加到网络流中,跑一遍最大流 2.记录下的所有最短路径,再加到新的最短路的图中,边权为1,跑一遍最短路,m-最短路 就是答案 注意:有重边的情况 比如: 2 3 1 2 1 1 2 1 1 2 1 ans: 3 2

hdu 5294 Tricks Device(最短路 + 最大流)

hdu 5294 Tricks Device 题目大意:吴邪在古墓中追张起灵,古墓中有很多条路,走每条路都需要一个时间,吴邪只有在最短的时间从古墓的入口到达出口才能追上张起灵.但是张起灵很厉害,他可以使用奇门遁甲使一条路无法通行.现在,问,张起灵最少堵住几条路就可以使吴邪追不上他,以及在吴邪可以追上张起灵的情况下,张起灵最多能堵多少条路. 解题思路:先求出古墓中的最短路(耗时最少的路),再求最短路的同时,记录走最短路要通过哪几条路和走最短路最少通过的路数.最多能堵住的路就是总的路数减去走最短路所

uva 11374 最短路+记录路径 dijkstra最短路模板

UVA - 11374 Airport Express Time Limit:1000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu [Submit]  [Go Back]  [Status] Description ProblemD: Airport Express In a small city called Iokh, a train service, Airport-Express, takes residents to t

HDU 5294 Tricks Device(多校2015 最大流+最短路啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Problem Description Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu's at the entrance of the tomb while Dumb Zhang's at the end of it. The tomb is made up of many chambers, the total

hdu5294 Tricks Device 最短路+最小割 多校联合第一场

Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 66    Accepted Submission(s): 14 Problem Description Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu's at the entra

最短路 + 记录路径 之 zoj 1456 Minimum Transport Cost (hdu 1385)

/* 考虑到测试数据中需要求解任意两点间的最短路,所以采用Floyd-Warshall算法 dp[i][j] = min(dp[i][k] + dp[k][j] + tax[k], dp[i][j]); 关键在于记录路径,并且要保证:if there are more minimal paths, output the lexically smallest one. 分两种情况讨论: (1)dp[i][j] > dp[i][k] + dp[k][j] + tax[k] 直接更新dp[i][j],

[bzoj1001][BeiJing2006]狼抓兔子-题解[平面图最小割转最短路]/[Dinic求最小割]

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路

hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那个人只有通过最短路径才能追上终点的那个人,而终点的那个人能切断任意路径. 第一问--终点那人要使起点那人不能追上的情况下可以切的最少的路径数,输出最少的路径数 第二问--起点那人能追上终点那人的情况下,终点那人能切断的最多的路径数,输出最多的路径数 思路:要使起点那人无法追上,只要使他的最短路径不存在就