usaco 4.3.4 Street Race

来源:互联网 发布:凶暴的男人知乎 编辑:程序博客网 时间:2024/05/01 12:00
/*ID: daniel.20LANG: JAVATASK: 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又是拿有向图做的,虽然过了,但是悲剧在于开始理解错了题意。

0 0
原创粉丝点击