码迷,mamicode.com
首页 > 其他好文 > 详细

西电10.9校内赛补题

时间:2017-10-11 11:08:51      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:队列   存在   int   sort   lag   spfa   imp   typedef   sync   

 

 

D.UVa12880

解题关键:dfs,判断每个人是否愿意被其他人交换,注意保证每个人只能被交换一次。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<iostream>
 7 #define maxn 220000
 8 using namespace std;
 9 typedef long long ll;
10 struct Edge{
11     int nxt;
12     int to;
13 }e[maxn];
14 int head[maxn],cnt,pre[maxn];
15 bool vis[maxn];
16 void add_edge(int u,int v){//单向
17     e[cnt].to=v;
18     e[cnt].nxt=head[u];
19     head[u]=cnt++;
20 }
21 bool dfs(int u){
22     for(int i=head[u];i!=-1;i=e[i].nxt){
23         int v=e[i].to;
24         if(vis[v]) continue;
25         vis[v]=true;
26         if(pre[v]==-1||dfs(pre[v])){
27             pre[v]=u;
28             return true;
29         }
30     }
31     return false;
32 }
33 int main(){
34     int n,m,a,b;
35     while(scanf("%d%d",&n,&m)!=EOF){
36         memset(head, -1, sizeof head);
37         memset(pre,-1,sizeof pre);
38         cnt=0;
39         for(int i=0;i<m;i++){
40             scanf("%d%d",&a,&b);
41             add_edge(a,b);
42         }
43         for(int i=0;i<n;i++){
44             memset(vis,0,sizeof vis);
45             dfs(i);
46         }
47         bool flag=false;
48         for(int i=0;i<n;i++){
49             if(pre[i]==-1){
50                 flag=true;
51                 break;
52             }
53         }
54         if(flag) printf("NO\n");
55         else printf("YES\n");
56     }
57     return 0;
58 }
View Code

 

 

E.hdu4313

解题关键:正向的思路是将边从小到大排序,如果去掉某条边,两个特殊点并起来了,则需去掉该边,我们反向考虑,将边从大到小排序,依次向图中加边,如果两个点并起来了,则需去掉该边。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<vector>
 7 #include<cmath>
 8 #define maxn 100020
 9 using namespace std;
10 typedef long long ll;
11 int par[maxn],n,k;
12 //bool vis[maxn];
13 struct edge{
14     int u;
15     int v;
16     int w;
17 }e[maxn];
18 bool flag[maxn];
19 bool cmp(const edge &a,const edge &b){
20     return a.w>b.w;
21 }
22 void init1(){
23     for(int i=0;i<=n;i++) par[i]=i;
24 }
25 
26 int find1(int x){
27     if(par[x]==x) return x;
28     else return par[x]=find1(par[x]);
29 }
30 
31 void unite(int x,int y){
32     par[x]=y;
33 }
34 
35 int main(){
36     int t,a;
37     ios::sync_with_stdio(0);
38     cin>>t;
39     while(t--){
40         memset(flag, 0, sizeof flag);
41         cin>>n>>k;
42         init1();
43         for(int i=0;i<n-1;i++){
44             cin>>e[i].u>>e[i].v>>e[i].w;
45         }
46         sort(e,e+n-1,cmp);
47         for(int i=0;i<k;i++){
48             cin>>a;
49             flag[a]=1;
50         }
51         ll ans=0;
52         for(int i=0;i<n-1;i++){
53             if(flag[find1(e[i].u)]&&flag[find1(e[i].v)]){
54                 ans+=e[i].w;
55             }
56             else if(flag[find1(e[i].u)]){
57                 unite(find1(e[i].v),find1(e[i].u));
58             }else{
59                 unite(find1(e[i].u), find1(e[i].v));
60             }
61         }
62         cout<<ans<<"\n";
63     }
64     return 0;
65 }
View Code

 

G.hdu4318

解题关键:最短路转化为最长路。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<cmath>
 7 #include<queue>
 8 using namespace std;
 9 const int maxn=50002;
10 const int maxm=2600010;
11 int head[maxn],tot,n,m;
12 struct edge{
13     int to;
14     double w;
15     int nxt;
16 }e[maxm];
17 void add_edge(int u,int v,double w){
18     e[tot].w=w;
19     e[tot].to=v;
20     e[tot].nxt=head[u];
21     head[u]=tot++;
22 }
23 bool vis[maxn];
24 queue<int>que;//队列是点的队列
25 double d[maxn];
26 void spfa(int s){
27     for(int i=0;i<=n;i++) d[i]=0.0;
28     memset(vis,0,sizeof vis);
29     while (!que.empty()) que.pop();
30     que.push(s);
31     vis[s]=true;
32     d[s]=1.0;
33     while (!que.empty()){
34         int u=que.front();
35         que.pop();
36         vis[u]=false;
37         for (int i=head[u];i!=-1;i=e[i].nxt){
38             int v=e[i].to;
39             double w=e[i].w;
40             if (d[v]<d[u]*w){
41                 d[v]=d[u]*w;
42                 if (!vis[v]){
43                     vis[v]=true;
44                     que.push(v);//hash一下,可判断是否存在负环
45                 }
46             }
47         }
48     }
49 }
50 int main(){
51     int a,b,k,td;
52     //double c;
53     while(scanf("%d",&n)!=EOF){
54         memset(head, -1, sizeof head);
55         tot=0;
56         for(int i=0;i<n;i++){
57             scanf("%d",&k);
58             for(int j=0;j<k;j++){
59                 scanf("%d%d",&b,&td);
60                 add_edge(i+1,b,1-td*0.01);
61             }
62         }
63         scanf("%d%d%d",&a,&b,&td);
64         spfa(a);
65         if(d[b]==0){
66             printf("IMPOSSIBLE!\n");
67         }else{
68             printf("%.2f\n",td-td*d[b]);
69         }
70     }
71     return 0;
72 }
View Code

 

西电10.9校内赛补题

标签:队列   存在   int   sort   lag   spfa   imp   typedef   sync   

原文地址:http://www.cnblogs.com/elpsycongroo/p/7648697.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!