开始以为是最长路,想着把每一门课程的每一节课时作为一个点去建有向图。。。然后写的时候发现点太多了(300*7*12)建图特麻烦,就果断放弃了这个思路。
然后开始用排除法来想用什么算法合适,没环不可能缩点,源点汇点非常不明显不像最大流,什么最小生成树啊就更不可能了。那就是二分了,可是怎么分呢?我就想输出的是最多能上多少门课,答案肯定小于等于n(课程数目),给你了每门课程的所有时间,哎呀!用每门课程去匹配一个合适的时间不就完了吗?最大匹配数一定小于等于n。
上代码
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 #define maxn 80000 6 using namespace std; 7 8 int n; 9 vector<int> g[maxn]; 10 int link[maxn],vis[maxn]; 11 12 int dfs(int x) 13 { 14 for(int i=0;i<g[x].size();i++) 15 { 16 int e = g[x][i]; 17 if(!vis[e]) 18 { 19 vis[e]=1; 20 if(link[e]==-1||dfs(link[e])) 21 { 22 link[e]=x; 23 return true; 24 } 25 } 26 } 27 return false; 28 } 29 void solve() 30 { 31 int sum=0; 32 memset(link,-1,sizeof(link)); 33 for(int i=1;i<=n;i++) 34 { 35 memset(vis,0,sizeof(vis)); 36 if(dfs(i)) sum++; 37 } 38 printf("%d\n",sum); 39 } 40 int main() 41 { 42 while(scanf("%d",&n)!=EOF) 43 { 44 for(int k=1;k<=n;k++) 45 g[k].clear(); 46 for(int i=1;i<=n;i++) 47 { 48 int m; 49 scanf("%d",&m); 50 for(int j=1;j<=m;j++) 51 { 52 int a,b; 53 scanf("%d%d",&a,&b); 54 g[i].push_back(12*(a-1)+b); 55 } 56 } 57 solve(); 58 } 59 return 0; 60 }
时间: 2024-10-13 07:08:53