十一届河南省赛-checkpoints(个人解法)-能AC代码

大致题意:

zznuoj,大致题意:从A点出发达到B点去解救人质,再从B点返回到A点,经历第二遍的点只计算一次即可,AB两点不计数!求完成任务最少需要经过的点数。
大致思路:暴力!从起点到终点,和从终点到起点这两趟路其实恰好可以分开,互不影响地进行取并集计算找最佳值!
          BFS枚举前1000条从起点A到终点B的路径(仅统计每种搜索的经过的点数)进set1,然后反之再搜索一次再统计一遍存进set2!然后两两求出交集后取并集最小的哪一个就是结果。
         当然BFS时要舍远求近,仅保留前1000个最短的路径,两次bfs其实步骤一样——对调起点和终点即可!
        优化:set<int>mp1[N];  //可替换成bool,再开一个bool数组再进行比较。

题解:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<queue>
  7 #include<set>
  8 using namespace std;
  9 #define inf 0x3f3f3f3f  
 10 #define N 108
 11 #define ll long long
 12 #define mem(a,x) memset(a,x,sizeof(a))  ///peace keeper
 13 
 14 set<int>mp1[N];  //可替换成bool,再开一个bool数组再进行比较
 15 set<int>mp2[N];
 16 
 17 vector<int>a[N];
 18 
 19 int n,m,A,B;
 20 int val[N];
 21 bool vis[N];
 22 struct node{
 23     int x,step;     //x表示当前的走到的那个的点,step表示抵达当前点走过的步数。
 24     bool vis[N];      //统计抵达当前点x的所有点
 25     bool operator< (const node &p)const{
 26       return p.step<step;///step小的先出去
 27     };
 28 };
 29 void debug(bool y[],int n){
 30     for(int i=1;i<=n;i++)
 31         printf(" %d",y[i]);
 32     cout<<endl;
 33 }
 34 int bfs1(int A,int B,int n){
 35     queue<node>Q;
 36     node st,next,now;
 37     st.x=A;st.step=0;mem(st.vis,0);st.vis[A]=1;
 38     Q.push(st);
 39     int cnt=0;
 40 
 41     while(Q.size()>0){
 42         now=Q.front();
 43         Q.pop();
 44         if(cnt>=100)break ;
 45         for(int i=0;i<(int)a[now.x].size();i++){
 46             int v=a[now.x][i];
 47 //            printf("%d->%d\n",now.x,v);
 48             if(!now.vis[v])
 49             {
 50                 next=now;
 51                 next.vis[v]=1;
 52 
 53                 next.x=v;next.step=now.step+1;
 54             ///    debug(next.vis,n);
 55                 if(v==B){
 56                     cnt++;
 57                     mp1[cnt].clear();
 58                     for(int j=1;j<=n;j++)
 59                     {
 60                         if(next.vis[j])mp1[cnt].insert(j);
 61                     }
 62                     continue;
 63                 }
 64 
 65                 Q.push(next);
 66             }
 67         }
 68     }
 69     return cnt;
 70 }
 71 int bfs2(int A,int B,int n){  //反向搜索一波,找寻N条最短路
 72     queue<node>Q;
 73     node st,next,now;
 74     st.x=B;st.step=0;mem(st.vis,0);st.vis[B]=1;
 75     Q.push(st);
 76     int cnt=0;
 77 
 78     while(Q.size()>0){
 79         now=Q.front();
 80         Q.pop();
 81         if(cnt>=100)break ;
 82         for(int i=0;i<(int)a[now.x].size();i++){
 83             int v=a[now.x][i];
 84  //   printf("%d->%d\n",now.x,v);
 85             if(!now.vis[v])
 86             {
 87                 next=now;
 88                 next.vis[v]=1;
 89                 next.x=v;next.step=now.step+1;
 90                 if(v==A){
 91                     cnt++;
 92                     mp2[cnt].clear();
 93                     for(int j=1;j<=n;j++)
 94                     {
 95                         if(next.vis[j])mp2[cnt].insert(j);
 96                     }
 97                     continue;
 98                 }
 99                 Q.push(next);
100             }
101         }
102     }
103     return cnt;
104 }
105 
106 int solve(int cnt1,int cnt2){
107 
108 
109     int ans=inf;
110     for(int i=1;i<=cnt1;i++){
111         for(int j=1;j<=cnt2;j++){
112             set<int>mp;
113             set<int>::iterator it;
114             for(it=mp1[i].begin();it!=mp1[i].end();++it){
115                 mp.insert(*it);
116         //       printf("[%d] ",*it);
117             }
118         //    cout<<" *** ";
119             for(it=mp2[j].begin();it!=mp2[j].end();++it){
120                 mp.insert(*it);
121         //        printf("(%d) ",*it);
122             }
123             ans=min(ans,(int)mp.size());
124        //     cout<<endl;
125         }
126     }
127     return ans-2;
128 }
129 
130 int main(){
131 
132     int T;
133     cin>>T;
134     while(T--){
135         scanf("%d%d%d%d",&n,&m,&A,&B);
136         int xi,yi;
137       //  memset(val,inf,sizeof(val));
138         for(int i=1;i<=n;i++)
139             a[i].clear();
140 
141         for(int i=1;i<=m;i++)
142         {
143             scanf("%d %d",&xi,&yi);
144             a[xi].push_back(yi);
145         }
146         if(A==B){
147             printf("0\n");continue;
148         }
149         int cnt1=bfs1(A,B,n);
150         int cnt2=bfs2(A,B,n);
151 
152         printf("%d\n",solve(cnt1,cnt2));
153     }
154 
155     return 0;
156 }
View Code

猜你喜欢

转载自www.cnblogs.com/zhazhaacmer/p/9768892.html