*感谢两位浙江大佬带我飞
贴下成绩
div2
div1
*div2不是我打的上个厕所就5/11了
比赛小结
A
【题目大意】
有n(n<=500)个机场,两两之间距离是g[i][j],每经停一个机场需要p[i]的时间维修
有m条线路,描述为出发机场,终点机场,出发时间,求航空公司至少需要多少架飞机
每条航线必须直飞
但是转机的时候可以劲停多个机场
【题解】
首先一架飞机能在完成航线A后去飞航线B的条件很显然。就是
表示两点间最短路。那么我们可以用这个不等式把问题转化为最小路径覆盖问题
我想了下这个最短路用Floyd吧n^3我选择死亡时限是5s应该能过的
然后忧虑了一下我的dinic的常数,写了个匈牙利,但是之后有人和我讲dinic更快?
#include<map> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<complex> #include<iostream> #include<assert.h> #include<algorithm> using namespace std; #define inf 1001001001 #define infll 1001001001001001001LL #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i)) #define ll long long #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl #define gmax(a,b) (a)=max((a),(b)) #define gmin(a,b) (a)=min((a),(b)) #define ios0 ios_base::sync_with_stdio(0) #define Ri register int #define gc getchar() #define il inline #define FOR1(i,n) for(Ri (i)=1;(i)<=(n);++(i)) il int read(){ bool f=true; Ri x=0;char ch; while(!isdigit(ch=gc))if(ch=='-')f=false; while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;} return f?x:-x; } #define gi read() int n,m,p[555],g[555][555],f[555][555]; struct edge{ int to,next; }e[555*555],s1[555],s2[555]; int cnt,last[666],match[666],vis[666]; void insert(int a,int b){ e[++cnt]=(edge){b,last[a]};last[a]=cnt; } int hungary(int u){ vis[u]=1; for(int i=last[u];i;i=e[i].next){ int y=e[i].to; if(match[y]==-1){ match[y]=u; return 1; } } for(int i=last[u];i;i=e[i].next){ int y=e[i].to; if(!vis[match[y]]&&hungary(match[y])){ match[y]=u; return 1; } } return 0; } int main(){ n=gi;m=gi; FOR1(i,n)p[i]=gi; FOR1(i,n)FOR1(j,n){ int T=gi; if(i^j)g[i][j]=T+p[j]; else g[i][j]=T; f[i][j]=g[i][j]; } //n^3 floyd FOR1(k,n)FOR1(i,n)FOR1(j,n)gmin(f[i][j],f[i][k]+f[k][j]); FOR1(i,m){ int a,b,c; a=gi;b=gi;c=gi; s1[i]=(edge){a,c}; s2[i]=(edge){b,c+g[a][b]}; } FOR1(i,m){ match[i]=-1; FOR1(j,m)if(i^j){ if(s2[i].next+f[s2[i].to][s1[j].to]<=s1[j].next)insert(i,j); } } int fyb=n; FOR1(i,m){ memset(vis,0,sizeof(vis)); if(hungary(i))--fyb; } printf("%d",fyb); return 0; }
C
【题目大意】
有n个人,他们的评级是由上(upper)中(middle)下(lower)组成的
两个评级的高底是从最后一个开始比较到第一个,一个中文的世纪大难题
求出从高到低的排列顺序
【题解】分类并排序md这都什么鬼题目啊
#include<map> #include<stack> #include<queue> #include<cstdio> #include<string.h> #include<vector> #include<cstring> #include<complex> #include<iostream> #include<assert.h> #include<algorithm> using namespace std; #define inf 1001001001 #define infll 1001001001001001001LL #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i)) #define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i)) #define ll long long #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl #define gmax(a,b) (a)=max((a),(b)) #define gmin(a,b) (a)=min((a),(b)) #define ios0 ios_base::sync_with_stdio(0) #define Ri register int #define gc getchar() #define il inline il int read(){ bool f=true; Ri x=0;char ch; while(!isdigit(ch=gc))if(ch=='-')f=false; while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;} return f?x:-x; } #define gi read() #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); int n; struct data{ char name[299]; int b[50]; bool operator<(data B)const{ for(int i=1;i<=49;i++) if(b[i]!=B.b[i]) return b[i]>B.b[i]; return strcmp(name,B.name)<0; } }a[1010]; int main(){ n=gi; FOR1(i,n){ scanf("%s",a[i].name);a[i].name[strlen(a[i].name)-1]='