hdu 3729 2010 Asia Tianjin Regional Contest

比如第i个学生是 【a b】

那就从i向a至b连边

左边是学生,右边是排名

二分匹配即可

View Code
 1 #include<stdio.h>
2 #include<string.h>
3 int map[62][100001];
4 int match[100010];
5 bool vis[100010];
6 int mi,mx;
7 bool dfs(int u)
8 {
9 int i;
10 for(i=mi;i<=mx;i++)
11 {
12 if(map[u][i]&&!vis[i])
13 {
14 vis[i]=1;
15 if(match[i]==-1||dfs(match[i]))
16 {
17 match[i]=u;
18 return true;
19 }
20 }
21 }
22 return false;
23 }
24 int main()
25 {
26 int t,n;
27 int ret[110];
28 int i,j,a,b;
29 scanf("%d",&t);
30 while(t--)
31 {
32 mx=-1,mi=100010;
33 scanf("%d",&n);
34 memset(map,0,sizeof(map));
35 memset(match,-1,sizeof(match));
36 for(i=1;i<=n;i++)
37 {
38 scanf("%d%d",&a,&b);
39 for(j=a;j<=b;j++)
40 map[i][j]=1;
41 if(a<mi) mi=a;
42 if(b>mx) mx=b;
43 }
44 int ans=0;
45 for(i=n;i>=1;i--)
46 {
47 memset(vis,0,sizeof(vis));
48 if(dfs(i))
49 {
50 ret[ans++]=i;
51 }
52 }
53 printf("%d\n",ans);
54 for(i=ans-1;i>=0;i--)
55 {
56 if(i==0)
57 printf("%d",ret[i]);
58 else printf("%d ",ret[i]);
59 }
60 printf("\n");
61 }
62 return 0;
63 }


换了一下方法,快了不止一点点啊,每次都在某个学生所能连到的地方搜就好了,具体见代码

View Code
 1 #include<stdio.h>
2 #include<string.h>
3 struct node{
4 int x,y;
5 }stu[61];
6 int match[100010];
7 bool vis[100010];
8 int mi,mx;
9 bool dfs(int u)
10 {
11 int i;
12 for(i=stu[u].x;i<=stu[u].y;i++)
13 {
14 if(!vis[i])
15 {
16 vis[i]=1;
17 if(match[i]==-1||dfs(match[i]))
18 {
19 match[i]=u;
20 return true;
21 }
22 }
23 }
24 return false;
25 }
26 int main()
27 {
28 int t,n;
29 int ret[110];
30 int i,j,a,b;
31 scanf("%d",&t);
32 while(t--)
33 {
34 mx=-1,mi=100010;
35 scanf("%d",&n);
36 for(i=1;i<=n;i++)
37 {
38 scanf("%d%d",&a,&b);
39 stu[i].x=a,stu[i].y=b;
40 if(a<mi) mi=a;
41 if(b>mx) mx=b;
42 }
43 for(i=mi;i<=mx;i++) match[i]=-1;
44 int ans=0;
45 for(i=n;i>=1;i--)
46 {
47 memset(vis,0,sizeof(vis));
48 if(dfs(i))
49 {
50 ret[ans++]=i;
51 }
52 }
53 printf("%d\n",ans);
54 for(i=ans-1;i>=0;i--)
55 {
56 if(i==0)
57 printf("%d",ret[i]);
58 else printf("%d ",ret[i]);
59 }
60 printf("\n");
61 }
62 return 0;
63 }



你可能感兴趣的:(test)