8.5
#include<stdio.h> int main() { int N; scanf("%d",&N); int queue[N]; //记录每个轨道的最小序号 int queueNum=0; //轨道数量 int num; for (int i = 0; i < N; i++) { scanf("%d", &num); if (i == 0 || num > queue[queueNum]) { //新数大于所有轨道中的最小序号时,添加新轨道。 //在维护过程中,最后加入的轨道永远存在着当前最大的序号,所以将新数与最后加入的轨道比较就行 queue[++queueNum] = num; } else { //新数小于最后加入的轨道中的序号时,将其插入与其差值最小的子串中去 //使用顺序查找时有测试点超时,所以这里用二分来找 int l=0;int r=queueNum;int mid; while(l<=r) { mid=(l+r)/2; if(queue[mid]>num)r=mid-1; else l=mid+1; } queue[l]=num; } } printf("%d",queueNum); }
#include <iostream> using namespace std; int fcode[501];//父节点集 int road[5001][2]; int flag[501]; void resum(int n) { //初始化 for (int i = 0; i < n; i++) { fcode[i] = i; }; } int findf(int a) { int f = a; while (f != fcode[f]) { f = fcode[f]; }; //压缩路径 while (fcode[a] != f) { int x = fcode[a];//记录a的直属下一节点 fcode[a] = f;//将a的下一节点改为根节点 a = x;//准备下一轮压缩 }; return f; } int bcj(int n, int m) { for (int i = 0; i < m; i++) { if (!flag[road[i][0]] || !flag[road[i][1]]) { continue; }; int fa = findf(road[i][0]); int fb = findf(road[i][1]); fcode[fb] = fa; }; int sum = 0; //压缩一遍 for (int i = 0; i < n; i++) { findf(i); }; for (int i = 0; i < n; i++) { if (!flag[i]) { continue; }; if (fcode[i] == i) { sum++; }; }; return sum; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { flag[i] = 1; }; for (int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); road[i][0] = a; road[i][1] = b; }; resum(n); int rsum = bcj(n, m); int num, sum; scanf("%d", &num); for (int i = 0; i < num; i++) { if (i != 0) { printf("\n"); }; int code; scanf("%d", &code); resum(n); flag[code] = 0; sum = bcj(n, m); if (sum > rsum) { printf("Red Alert: City "); printf("%d", code); printf(" is lost!"); } else { printf("City "); printf("%d", code); printf(" is lost."); }; rsum = sum; }; if (rsum == 0) { printf("\n"); printf("Game Over."); }; }