[NOIP2013]车站分级
Here
解题思路
- 由于起始点之间所选的站号,相互之间一定满足
- 那么对于起始点间未选择的站号,一定满足选择的站号
- 考虑用边来维护信息,表示的级别大于
- 按题意,则车站会被分为几个联通块,且保证块内无环,即一定存在一个有序序列
- 则通过拓扑排序,找到连通块内的最长路径,即为最小的必要分级数
import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;public class Main{static long md=(long)998244353;static long Linf=Long.MAX_VALUE/2;static int inf=Integer.MAX_VALUE/2;public static void main(String[] args) throws IOException{AReader input=new AReader();PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); /** 用有向边维护大于号* 按题意,则车站会被分为几个联通块,且保证块内无环,即一定存在一个有序序列* 最长的序列即为最小的必要分级数*/int n=input.nextInt();int m=input.nextInt();boolean[][] e=new boolean[n+1][n+1];boolean[] vis=new boolean[n+1];int[] st=new int[n+1];int[] in=new int[n+1];for(int i=1;i<=m;++i) {int t=input.nextInt();Arrays.fill(vis, false);for(int j=1;j<=t;++j) {int x=input.nextInt();vis[x]=true;st[j]=x;}for(int j=st[1];j<=st[t];++j) {if(vis[j])continue;for(int k=1;k<=t;++k) {if(e[st[k]][j])continue;e[st[k]][j]=true;in[j]++;}}}Queue<Integer> q=new LinkedList<Integer>();for(int i=1;i<=n;++i)if(in[i]==0)q.add(i);int[] a=new int[n+1];Arrays.fill(a, 1);while(!q.isEmpty()) {int x=q.peek();q.poll();for(int i=1;i<=n;++i) {if(e[x][i]) {a[i]=Math.max(a[i], a[x]+1);in[i]--;if(in[i]==0)q.add(i);}}}int mx=0;for(int i=1;i<=n;++i)mx=Math.max(mx, a[i]);out.print(mx);out.flush();out.close();}//System.out.println();//out.println();staticclass AReader{ BufferedReader bf;StringTokenizer st;BufferedWriter bw;public AReader(){bf=new BufferedReader(new InputStreamReader(System.in));st=new StringTokenizer("");bw=new BufferedWriter(new OutputStreamWriter(System.out));}public String nextLine() throws IOException{return bf.readLine();}public String next() throws IOException{while(!st.hasMoreTokens()){st=new StringTokenizer(bf.readLine());}return st.nextToken();}public char nextChar() throws IOException{//确定下一个token只有一个字符的时候再用return next().charAt(0);}public int nextInt() throws IOException{return Integer.parseInt(next());}public long nextLong() throws IOException{return Long.parseLong(next());}public double nextDouble() throws IOException{return Double.parseDouble(next());}public float nextFloat() throws IOException{return Float.parseFloat(next());}public byte nextByte() throws IOException{return Byte.parseByte(next());}public short nextShort() throws IOException{return Short.parseShort(next());}public BigInteger nextBigInteger() throws IOException{return new BigInteger(next());}public void println() throws IOException {bw.newLine();}public void println(int[] arr) throws IOException{for (int value : arr) {bw.write(value + " ");}println();}public void println(int l, int r, int[] arr) throws IOException{for (int i = l; i <= r; i ++) {bw.write(arr[i] + " ");}println();}public void println(int a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(int a) throws IOException{bw.write(String.valueOf(a));}public void println(String a) throws IOException{bw.write(a);bw.newLine();}public void print(String a) throws IOException{bw.write(a);}public void println(long a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(long a) throws IOException{bw.write(String.valueOf(a));}public void println(double a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(double a) throws IOException{bw.write(String.valueOf(a));}public void print(char a) throws IOException{bw.write(String.valueOf(a));}public void println(char a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}}
}
P4366 [Code+#4] 最短路
Here
解题思路
- 主要是对于,如何处理,避免建条边
- 考虑二进制
- ,可以看作是通过某些的边到达
- 设,则,建边
- 然后跑最短路即可
- 注意,需要添一点0
- 边总共有
- 洛谷该题内存不够,可以点链接去牛客交
import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;//implements Runnable
public class Main{static long md=(long)998244353;static long Linf=Long.MAX_VALUE/2;static int inf=Integer.MAX_VALUE/2;static int N=500010+20*100010;static int n=0;static int m=0;static int c=0;staticclass Edge{int fr,to,nxt;int val;public Edge(int u,int v,int w) {fr=u;to=v;val=w;}}static Edge[] e;static int[] head;static int cnt=0;static void addEdge(int fr,int to,int val) {cnt++;e[cnt]=new Edge(fr, to, val);e[cnt].nxt=head[fr];head[fr]=cnt;}staticclass Node{int x;int y;public Node(int u,int v) {x=u;y=v;}}static int Dij(int s,int t) {int[] dis=new int[n+1];Arrays.fill(dis, inf);boolean[] vis=new boolean[n+1];dis[s]=0;PriorityQueue<Node> q=new PriorityQueue<Node>((o1,o2)->{return o1.y-o2.y;});q.add(new Node(s, 0));while(!q.isEmpty()) {Node now=q.peek();q.poll();int x=now.x;if(vis[x])continue;vis[x]=true;for(int i=head[x];i>0;i=e[i].nxt) {int v=e[i].to;int w=e[i].val;if(vis[v])continue;if(dis[v]>dis[x]+w) {dis[v]=dis[x]+w;q.add(new Node(v, dis[v]));}}}return dis[t];}static void solve() throws Exception{AReader input=new AReader();PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); n=input.nextInt();m=input.nextInt();c=input.nextInt();e=new Edge[m+20*n+1];head=new int[n+1];cnt=0;for(int i=1;i<=m;++i) {int u=input.nextInt();int v=input.nextInt();int w=input.nextInt();addEdge(u, v, w);}for(int i=0;i<=n;++i) {for(int j=1;j<=n;j<<=1) {int x=i^j;if(x>n)continue;addEdge(i, x, j*c);}}int s=input.nextInt();int t=input.nextInt();out.print(Dij(s, t));out.flush();out.close();}public static void main(String[] args) throws Exception{solve();}
// public static final void main(String[] args) throws Exception {
// new Thread(null, new Main(), "线程名字", 1 << 27).start();
// }
// @Override
// public void run() {
// try {
// //原本main函数的内容
// solve();
//
// } catch (Exception e) {
// }
// }staticclass AReader{ BufferedReader bf;StringTokenizer st;BufferedWriter bw;public AReader(){bf=new BufferedReader(new InputStreamReader(System.in));st=new StringTokenizer("");bw=new BufferedWriter(new OutputStreamWriter(System.out));}public String nextLine() throws IOException{return bf.readLine();}public String next() throws IOException{while(!st.hasMoreTokens()){st=new StringTokenizer(bf.readLine());}return st.nextToken();}public char nextChar() throws IOException{//确定下一个token只有一个字符的时候再用return next().charAt(0);}public int nextInt() throws IOException{return Integer.parseInt(next());}public long nextLong() throws IOException{return Long.parseLong(next());}public double nextDouble() throws IOException{return Double.parseDouble(next());}public float nextFloat() throws IOException{return Float.parseFloat(next());}public byte nextByte() throws IOException{return Byte.parseByte(next());}public short nextShort() throws IOException{return Short.parseShort(next());}public BigInteger nextBigInteger() throws IOException{return new BigInteger(next());}public void println() throws IOException {bw.newLine();}public void println(int[] arr) throws IOException{for (int value : arr) {bw.write(value + " ");}println();}public void println(int l, int r, int[] arr) throws IOException{for (int i = l; i <= r; i ++) {bw.write(arr[i] + " ");}println();}public void println(int a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(int a) throws IOException{bw.write(String.valueOf(a));}public void println(String a) throws IOException{bw.write(a);bw.newLine();}public void print(String a) throws IOException{bw.write(a);}public void println(long a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(long a) throws IOException{bw.write(String.valueOf(a));}public void println(double a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(double a) throws IOException{bw.write(String.valueOf(a));}public void print(char a) throws IOException{bw.write(String.valueOf(a));}public void println(char a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}}}