acdream 1415 最短路+边联通求桥

题意:给你一幅无向图,让你找一些边,这些边满足以下条件:去掉任意一条这样的边,会使得从1走到n的时间增大或者无法从1走到n。


分析:首先求最短路,我们可以发现这些边一定是最短路径上面的边,然后直接将最短路径上面的边建新图,找桥即可。


代码:

#pragma comment(linker,"/STACK:102400000,102400000")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;   //ŒÇµÃ±ØÒªµÄʱºòžÄ³ÉÎÞ·ûºÅ
const int maxn=20005;   //µãÊý
const int maxm=300005;   //±ßÊý
const int INF=1000000000;
struct EdgeNode
{
    int from;
    int to;
    int w;
    int xu;
    int vis;
    int next;
}edge[maxm];
int head[maxn],cnt,sum;
void add(int x,int y,int z,int xu)
{
    edge[cnt].from=x;
    edge[cnt].to=y;
    edge[cnt].w=z;
    edge[cnt].xu=xu;
    edge[cnt].vis=0;
    edge[cnt].next=head[x];
    head[x]=cnt++;
}

void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}

int n,m,d[maxn],f[maxn];
bool vis[maxm];

void DJ(int st)
{
    int x,y,z;
    typedef pairp;
    priority_queue,greater

>Q; fill(d,d+n+2,INF); d[st]=0; Q.push(p(0,st)); while(!Q.empty()) { p t=Q.top(); Q.pop(); x=t.second; if(d[x]dfn[u]) { sum++; chu[sum]=edge[i].xu; } } else low[u]=min(low[u],dfn[v]); } } int main() { int i,x,y; while(~scanf("%d%d",&n,&m)) { init(); shuru(); DJ(1); for(i=1;i<=n;i++)f[i]=d[i]; DJ(n); sum=0; build(); dfs1(1); printf("%d\n",sum); for(i=1;i<=sum;i++){ if(i==1)printf("%d",chu[i]); else printf(" %d",chu[i]); } printf("\n"); } }




你可能感兴趣的:(强双联通,最短路,强双联通)