网络流24题——孤岛营救(分层图最短路)
作者:互联网
题目链接:https://loj.ac/problem/6121
解题报告:由于p很小,所以可以通过二进制表示当前是否有该点的钥匙,建完图跑最短路,其他的没什么难点了
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 #include<queue> 6 #include<cstring> 7 #include<algorithm> 8 #define numm ch-48 9 #define pd putchar(' ') 10 #define pn putchar('\n') 11 #define pb push_back 12 #define debug(args...) cout<<#args<<"->"<<args<<endl 13 #define bug cout<<"************" 14 using namespace std; 15 template <typename T> 16 void read(T &res) { 17 bool flag=false;char ch; 18 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 19 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 20 flag&&(res=-res); 21 } 22 template <typename T> 23 void write(T x) { 24 if(x<0) putchar('-'),x=-x; 25 if(x>9) write(x/10); 26 putchar(x%10+'0'); 27 } 28 typedef long long ll; 29 const int maxn=110+10; 30 const int inf=0x3f3f3f3f; 31 const int mod=1e9+7; 32 struct wtz { 33 int state,v; 34 wtz(){} 35 wtz(int state,int v):state(state),v(v){} 36 }; 37 struct node { 38 int v,net,w; 39 node(){} 40 node(int v,int net,int w):v(v),net(net),w(w){} 41 }e[maxn*maxn*4]; 42 int dx[4]={1,-1,0,0}; 43 int dy[4]={0,0,1,-1}; 44 int cnt,st,ed,id[maxn][maxn],a[maxn][maxn],dis[2100][maxn],head[maxn]; 45 int key[maxn],len; 46 void addedge(int u,int v,int w) { 47 e[cnt]=node(v,head[u],w); 48 head[u]=cnt++; 49 } 50 int spfa() { 51 queue<wtz>que; 52 que.push(wtz(1,st)); ///得到1号钥匙 53 dis[1][st]=0; 54 while(!que.empty()) { 55 wtz now=que.front(); 56 que.pop(); 57 int u=now.v; 58 dis[now.state|key[u]][u]=min(dis[now.state|key[u]][u],dis[now.state][u]); 59 now.state|=key[u]; ///得到u点的钥匙 60 for(int i=head[u];~i;i=e[i].net) { 61 int v=e[i].v; 62 if((now.state&e[i].w)==e[i].w) { ///state拥有这扇门的钥匙 63 if(dis[now.state][v]>dis[now.state][u]+1) { 64 dis[now.state][v]=dis[now.state][u]+1; 65 que.push(wtz(now.state,v)); 66 } 67 } 68 } 69 } 70 int ans=inf; 71 for(int i=1;i<2100;i++) 72 ans=min(ans,dis[i][ed]); 73 return ans==inf?-1:ans; 74 } 75 int main() 76 { 77 int m,n,p,k; 78 while(scanf("%d%d%d",&n,&m,&p)!=EOF) { 79 cnt=0,st=1,ed=n*m; 80 for(int i=1;i<=n;i++) { 81 for(int j=1;j<=m;j++) { 82 id[i][j]=++cnt; ///得到点(i,j)的线性标号 83 } 84 } 85 memset(dis,inf,sizeof(dis)); 86 memset(head,-1,sizeof(head)); 87 memset(a,-1,sizeof(a)); 88 memset(key,0,sizeof(key)); 89 int x1,x2,y1,y2,g; 90 cnt=0; 91 read(k); 92 for(int i=1;i<=k;i++) { 93 read(x1),read(y1),read(x2),read(y2),read(g); 94 int u=id[x1][y1]; 95 int v=id[x2][y2]; 96 a[u][v]=a[v][u]=g; 97 if(g) { 98 addedge(u,v,1<<g); 99 addedge(v,u,1<<g); 100 } 101 } 102 for(int i=1;i<=n;i++) { 103 for(int j=1;j<=m;j++) { 104 int u=id[i][j]; 105 for(int k=0;k<4;k++) { 106 int x=i+dx[k]; 107 int y=j+dy[k]; 108 if(x<1||y<1||x>n||y>m) continue; 109 int v=id[x][y]; 110 if(a[u][v]==-1) ///u和v之间没有墙和门,也可认为是1类门 111 addedge(u,v,1); 112 } 113 } 114 } 115 int s; 116 read(s); 117 for(int i=1;i<=s;i++) { 118 read(x1),read(y1),read(g); 119 key[id[x1][y1]]|=(1<<g); ///每个点存放的钥匙可以有多种 120 } 121 write(spfa());pn; 122 } 123 return 0; 124 }View Code
标签:24,include,int,短路,state,maxn,孤岛,now,dis 来源: https://www.cnblogs.com/wuliking/p/11586696.html