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 }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3313