您的位置:首页 > 其它

usaco 4.3.4 Street Race

2014-05-25 20:29 330 查看
/*
ID: daniel.20
LANG: JAVA
TASK: race3
*/

import java.util.*;
import java.io.*;

class edge1{
int from,to,next;
public edge1(int a,int b,int c){
from=a;to=b;next=c;
}
}
class problem3{
StringBuilder sb = new StringBuilder();
edge1[] undirG,dirG;
int[] header,header2,vis,cut,depth,low,cnt;
int index,index1,idx,node;
boolean[] mark;
int max=-1;
void solver() throws IOException{
long start = System.currentTimeMillis();
BufferedReader reader = new BufferedReader(new FileReader("race3.in"));
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("race3.out")));
undirG = new edge1[220];
dirG = new edge1[220];
header = new int[55];
header2 = new int[55];
depth = new int[55];
vis = new int[55];
cut = new int[55];
low = new int[55];
cnt = new int[55];
mark = new boolean[55];
Arrays.fill(header, -1);
Arrays.fill(header2, -1);
index=0;index1=0;node=0;
boolean done = false;
while(!done){
StringTokenizer st = new StringTokenizer(reader.readLine());
while(st.hasMoreTokens()){
int to = Integer.valueOf(st.nextToken());
if(to==-2) break;
if(to==-1) {
done=true; break;
}
undirG[index] = new edge1(node,to,header[node]);
header[node] = index++;
dirG[index1] = new edge1(node,to,header2[node]);
header2[node] = index1++;
undirG[index] = new edge1(to,node,header[to]);
header[to] = index++;

}
node++;
}
int s2=0;
for(int i=1;i<node-2;i++){
int backup = header2[i];
header2[i]=-1;
Arrays.fill(mark, false);
if(!dfs(0)){
s2++;
sb.append(" ").append(i);
}
header2[i]=backup;
}
sb.insert(0, s2);
System.out.println(sb.toString());
pw.println(sb.toString());
sb = new StringBuilder();
int s1=0;
tarjan(0,-1);
for(int i=1;i<cut.length-1;i++){
if(cut[i]>0){
boolean flag = true;
for(int j=header2[i];j!=-1;j=dirG[j].next){
int v = dirG[j].to;
if(depth[v]<depth[i]){
flag=false;
}
}
if(flag){
s1++;
sb.append(" ").append(i);
}
}
}
sb.insert(0, s1);
System.out.println(sb.toString());
pw.println(sb.toString());
pw.close();
System.out.println("$:"+(System.currentTimeMillis()-start));
System.exit(0);
}
void tarjan(int u, int pre){
int sons=0;
vis[u]=1;
low[u]=depth[u]=idx++;
for(int i=header[u];i!=-1;i=undirG[i].next){
int v = undirG[i].to;
if(vis[v]==1&&v!=pre){
low[u]=Math.min(low[u], depth[v]);
}
if(vis[v]==0){
tarjan(v,u);
sons++;
low[u]=Math.min(low[u], low[v]);
if((u==0&&sons>1)||(u!=0&&depth[u]<=low[v])){
cut[u]++;
}
}
}
vis[u]=2;
}
boolean dfs(int u){
if(u==node-2){
return true;
}
boolean flag = false;
for(int i=header2[u];i!=-1;i=dirG[i].next){
int v = dirG[i].to;
if(!mark[v]){
mark[v]=true;
flag|=dfs(v);
}
}
return flag;
}
}

public class race3 {
public static void main(String[] args) throws Exception {
problem3 p = new problem3();
p.solver();
}
}

这个题目写得又蛋疼了。

第一问好做,去掉点做flood fill.

第二问我理解错了,以为是求割点,其实不是割点。

严格的说split point属于割点的一部分,不同于割点的地方在于 split point所有出去的边必须是到下一个集合

就是说split point作为第一个集合的终点,不能有出去的边到第一个集合了

最好的做法网上太多了,也比较简单,不说了

我把求割点强行改了一下,如果割点能到的点比割点深度都大,那么就是split point

写得不好,割点把图转换成了无向图,然后flood fill又是拿有向图做的,虽然过了,但是悲剧在于开始理解错了题意。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: