hdu4738 Caocao's Bridges(tarjan / bridge + special judgment)

Keywords: less

subject

I n this paper, we give a n (n < = 1E3) point m (m < = n * n) edge graph. There are wi individuals (0 < = wi < = 1E4) on the i-th edge.

Blow up at most one edge of this picture at the cost that the number of people dispatched is not less than the number of people on the edge

Split the graph into two or more connecting blocks to minimize the number of dispatched people

Source of thought

https://www.cnblogs.com/kuangbin/p/3323369.html

Title Solution

To seek the bridge with the least value

① due to the large m and heavy edge, the chain forward star can solve the problem, but it should be noted that the reverse edge cannot be used when searching the bridge.

② if there are two or more connected blocks, it means that there is no need to explode, and the output is 0.

③ if there is no one on the bridge (i.e. the side weight of the bridge is 0), but at least one person must be sent to blow it up, output 1

Code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e3+10;
const int maxm=maxn*maxn*2;//Two way edge 
int n,m,head[maxn];
int cnt=1;//Note that the first edge is 2 to 2 ^ 3 
int dfn[maxn],low[maxn],num,tot;
bool bridge[maxm];
int u,v,w,ans;
struct edge
{
    int to,next,w;
}e[maxm];
void init()
{
	memset(head,0,sizeof head);
	memset(bridge,0,sizeof bridge);
	memset(dfn,0,sizeof dfn);
	memset(low,0,sizeof low);
	cnt=1;ans=INF;tot=0;
}
void add(int u,int v,int w)
{
    e[++cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void dfs(int u,int in)
{
    low[u]=dfn[u]=++num;
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if(!dfn[v])
        {
            dfs(v,i);
            low[u]=min(low[u],low[v]);
            if(low[v]>dfn[u])
            {
           	 bridge[i]=bridge[i^1]=1;
           	 ans=min(ans,e[i].w);
         	}
        }
        else if(i!=(in^1))
        low[u]=min(low[u],dfn[v]);
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
    	if(n==0&&m==0)break;
    	init();
    	for(int i=1;i<=m;++i)
    	{
     	   scanf("%d%d%d",&u,&v,&w);
     	   add(u,v,w);
		   add(v,u,w);
    	}
    	for(int i=1;i<=n;++i)
    	if(!dfn[i])tot++,dfs(i,0);
    	if(tot>1)puts("0");
    	else if(ans==INF)puts("-1");
    	else if(ans==0)puts("1");
    	else printf("%d\n",ans);
	}
    return 0;
}

 

Posted by Terminator on Fri, 01 Nov 2019 12:02:12 -0700