Luogu P1401 Ciudad

Solución 1:

Se puede decir que debe haber T caminos, entonces buscamos T caminos. Para cada búsqueda de ruta, el tramo de ruta más largo de la respuesta binaria esta vez, si se cumplen las condiciones, se marca la ruta. (Para la ruta marcada, no se puede usar en el futuro). A partir de esto, podemos obtener que la respuesta es la longitud de ruta más larga de la ruta de búsqueda T-ésima.
Complejidad de tiempo: O (T (n + m) logm), y la constante es relativamente grande.
Rockwell TLE 7
#include <bits/stdc++.h>
using namespace std;
const int N=205,M=4e4+5;
int n,m,t,u,v,w,tot,l,r,mid,ans,minn;
bool vis[N];
struct number{
    
    int x,y,w;}num[M<<1];
int cnt,head[N];
struct edge{
    
    int next,to,w,f;}e[M<<1];

inline bool cmp(number a,number b)
{
    
    
	return a.w<b.w;
}

bool dfs(int u,int w)
{
    
    
	vis[u]=true;
	if (u==n) return true;
	for (register int i=head[u]; i; i=e[i].next)
	if (!e[i].f && !vis[e[i].to] && e[i].w<=w)
	{
    
    
		if (dfs(e[i].to,w)) 
		{
    
    
			return true;	
		}
	}
	return false;
}
bool dfs2(int u,int w)
{
    
    
	vis[u]=true;
	if (u==n) return true;
	for (register int i=head[u]; i; i=e[i].next)
	if (!e[i].f && !vis[e[i].to] && e[i].w<=w)
	{
    
    
		if (dfs2(e[i].to,w))
		{
    
    
			e[i].f=1;
			return true;	
		}
	}
	return false;
}

inline bool jay(int mid)
{
    
    
	for (register int i=1; i<=n; ++i) vis[i]=false;
	return dfs(1,num[mid].w);
}

inline void add(int u,int v,int w)
{
    
    
	cnt++;
	e[cnt].next=head[u];
	e[cnt].to=v;
	e[cnt].w=w;
	head[u]=cnt;
}

int main(){
    
    
	scanf("%d%d%d",&n,&m,&t);
	for (register int i=1; i<=m; ++i)
	{
    
    
		scanf("%d%d%d",&u,&v,&w);
		tot++; num[tot].x=u; num[tot].y=v; num[tot].w=w;
		tot++; num[tot].x=v; num[tot].y=u; num[tot].w=w;	
		add(u,v,w); add(v,u,w);
	}
	
	sort(num+1,num+tot+1,cmp);
	while (t--)
	{
    
    
		l=1; r=tot; ans=0;
		while (l<=r)
		{
    
    
			mid=l+r>>1;
			if (jay(mid)) ans=mid,r=mid-1;
			else l=mid+1;
		}
		for (register int i=1; i<=n; ++i) vis[i]=false;
		dfs2(1,num[ans].w);
		minn=max(minn,num[ans].w);
	}
	printf("%d\n",minn);
return 0;
}

Solución 2:

Enumere la longitud máxima del lado Para el lado cuya longitud es menor que la longitud enumerada, la tasa de flujo se registra como 1. Si el flujo máximo es mayor o igual a T, la condición se cumple. Podemos pensar en respuestas de enumeración binaria, complejidad de tiempo: O (nmlogm).

Solución 3:

Si enumeramos la longitud máxima del lado en el orden de la longitud del lado de pequeña a grande, y solo ejecutamos el flujo máximo en la red residual cada vez, entonces la complejidad total de ejecutar el flujo máximo varias veces debería ser: O (nm).
#include <bits/stdc++.h>
using namespace std;
const int N=205,M=4e4+5,inf=2e9;
int n,m,T,tot,s,t;
int b[M],d[N];
int cnt=1,head[N];
struct edge{
    
    int next,to,w;}e[M<<1];
struct number{
    
    int x,y,w;}num[M];

inline bool cmp(number a,number b)
{
    
    
	return a.w<b.w;
}
inline void add(int u,int v,int w)
{
    
    
	cnt++;
	e[cnt].next=head[u];
	e[cnt].to=v;
	e[cnt].w=w;
	head[u]=cnt;
}
inline void insert(int u,int v)
{
    
    
	add(u,v,1); add(v,u,1);
}

queue<int>q;
inline bool bfs()
{
    
    
	memset(d,-1,sizeof(d));
	d[s]=0;
	q.push(s);
	while (q.size())
	{
    
    
		int u=q.front(); q.pop();
		for (register int i=head[u]; i; i=e[i].next)
		{
    
    
			if (e[i].w && d[e[i].to]==-1)
			{
    
    
				d[e[i].to]=d[u]+1;
				q.push(e[i].to);
			}
		}
	}
	if (d[t]==-1) return false;
	return true;
}
inline int dfs(int u,int flow)
{
    
    
	if (u==t) return flow;
	int last=flow;
	for (register int i=head[u]; i; i=e[i].next)
	{
    
    
		if (e[i].w && d[e[i].to]==d[u]+1)
		{
    
    
			int k=dfs(e[i].to,min(e[i].w,last));
			if (!k) {
    
    d[e[i].to]=-1; continue;}
			last-=k; e[i].w-=k; e[i^1].w+=k;
		}
		if (!last) break;
	}
	return flow-last;
}
inline int dinic()
{
    
    
	int ans=0;
	while (bfs()) ans+=dfs(s,inf);
	return ans; 
}

int main(){
    
    
	scanf("%d%d%d",&n,&m,&T);
	for (register int i=1; i<=m; ++i) 
	scanf("%d%d%d",&num[i].x,&num[i].y,&num[i].w),b[i]=num[i].w;
	sort(b+1,b+m+1);
	tot=unique(b+1,b+m+1)-b-1; 
	sort(num+1,num+m+1,cmp);
	int j=1;
	s=1; t=n;
	for (register int i=1; i<=tot; ++i)
	{
    
    
		while (j<=m && num[j].w<=b[i])
		{
    
    
			insert(num[j].x,num[j].y); 
			j++;	
		}
		T-=dinic();
		if (T<=0)
		{
    
    
			printf("%d\n",b[i]);
			return 0;
		}
	}
return 0;
}

Supongo que te gusta

Origin blog.csdn.net/Dove_xyh/article/details/108352780
Recomendado
Clasificación