hdu3313 求有向图s到t割点

首先spfa(思考dijkstra不够==)找一条最短路,若不存在,则n个点都符合。

从s进行dfs,找到能到达的最短路上的最远点,这个点就是割点。

然后下次以这个为起点dfs,直到找到t。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 #include<algorithm>
 5 #define INF 0x3f3f3f3f
 6 using namespace std;
 7 int now,st,ed;
 8 int head[100005],point[300005],next[300005];
 9 int used[100005],vis[100005],dis[100005],mark[100005],fa[100005];
10 void add(int u,int v)
11 {
12   next[++now]=head[u];
13   head[u]=now;
14   point[now]=v;
15 }
16 int spfa()
17 {
18   int tmp,u,v,i;
19   queue<int>q;
20   memset(used,0,sizeof(used));
21   memset(dis,0x3f,sizeof(dis));
22   memset(mark,0,sizeof(mark));
23   used[st]=1; dis[st]=0; q.push(st);
24   while (!q.empty())
25   {
26     u=q.front(); q.pop();
27     used[u]=0;
28     for (i=head[u];i;i=next[i])
29     {
30       v=point[i];
31       if (dis[u]+1<dis[v])
32       {
33         dis[v]=dis[u]+1;
34         fa[v]=u;
35         if (used[v]==0) {used[v]=1; q.push(v); }
36       }
37     }
38   }
39   if (dis[ed]==INF) return -1;
40   mark[st]=mark[ed]=1; tmp=ed;
41   while (tmp!=st)
42   {
43     mark[tmp]=1;
44     tmp=fa[tmp];
45   }
46   return dis[ed];
47 }
48 void scanf ( int& x , char c = 0 , int flag = 0 ) {
49     while ( ( c = getchar () ) != '-' && ( c < '0' || c > '9' ) ) ;
50     if ( c == '-' ) flag = 1 , x = 0 ;
51     else x = c - '0' ;
52     while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ;
53     if ( flag ) x = -x ;
54 }
55 void dfs(int u)
56 {
57   int v,i;
58   for (i=head[u];i;i=next[i])
59   {
60     v=point[i];
61     if (vis[v]) continue;
62     vis[v]=1;
63     if (mark[v])
64     {
65       if (dis[v]>dis[st]) st=v;
66       continue;
67     }
68     dfs(v);
69   }
70 }
71 int main()
72 {
73   int n,m,i,u,v,ans;
74   while (~scanf("%d%d",&n,&m))
75   {
76     memset(head,0,sizeof(head));
77     now=0;
78     for (i=1;i<=m;i++)
79     {
80       scanf(u); scanf(v);
81       u++; v++;
82       add(u,v);
83     }
84     scanf("%d%d",&st,&ed);
85     st++; ed++;
86     if (spfa()==-1) {printf("%d\n",n); continue; }
87     ans=1;
88     memset(vis,0,sizeof(vis));
89     while (st!=ed)
90     {
91       dfs(st);
92       ans++;
93     }
94     printf("%d\n",ans);
95   }
96   return 0;
97 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3313

 

转载于:https://www.cnblogs.com/xiao-xin/articles/4190888.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值