标签:通道 res cstring sid cto when memset str next
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
题意:一个图,#不可达,m条单向通道,点间花费1时间,通道起点到终点不花费时间,求最少花费时间;
思路:状态压缩dp,dp[i][j] i表示已经走过哪些通道,j表示最后的走的那条通道是哪条。
dp[i][j]=dp[i-(1<<(j-1)][k] +dis(k,j) dis(k,j)表示第k条通道的终点到第j条通道的起点距离;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> #include<bitset> #include<time.h> using namespace std; #define LL long long #define pi (4*atan(1.0)) #define eps 1e-8 #define bug(x) cout<<"bug"<<x<<endl; const int N=10+10,M=1e6+10,inf=1e9+7,MOD=1e9+7; const LL INF=1e18+10,mod=1e9+7; int n,m,vis[N][N]; char a[N][N]; struct is { int s,t,e,d; } q[N]; int check(int x,int y) { if(x<=0||x>n||y<=0||y>n)return 0; return 1; } int dis[N][N][N][N]; int xx[5]= {1,0,-1,0}; int yy[5]= {0,1,0,-1}; void bfs(int s,int t) { queue<pair<int,int> >q; q.push(make_pair(s,t)); memset(vis,0,sizeof(vis)); vis[s][t]=1;dis[s][t][s][t]=0; while(!q.empty()) { pair<int,int> p=q.front(); q.pop(); for(int i=0; i<4; i++) { int x=p.first+xx[i]; int y=p.second+yy[i]; if(check(x,y)&&!vis[x][y]&&a[x][y]==‘.‘) { vis[x][y]=1; dis[s][t][x][y]=dis[s][t][p.first][p.second]+1; q.push(make_pair(x,y)); } } } } int dp[50000][N]; int main() { while(~scanf("%d%d",&n,&m)) { memset(dis,-1,sizeof(dis)); for(int i=1; i<=n; i++) scanf("%s",a[i]+1); for(int i=1; i<=m; i++) scanf("%d%d%d%d",&q[i].s,&q[i].t,&q[i].e,&q[i].d); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)bfs(i,j); memset(dp,-1,sizeof(dp)); for(int i=1;i<=(1<<m)-1;i++) { for(int j=1;j<=m;j++) { if((1<<(j-1))&i) { int now=i-(1<<(j-1)); if(!now) { dp[i][j]=0; continue; } for(int k=1;k<=m;k++) { if(now&(1<<(k-1))) { if(dp[now][k]!=-1&&dis[q[k].e][q[k].d][q[j].s][q[j].t]!=-1) { int temp=dp[i][j]; dp[i][j]=dp[now][k]+dis[q[k].e][q[k].d][q[j].s][q[j].t]; if(temp!=-1)dp[i][j]=min(dp[i][j],temp); } } } } } } int ans=inf; for(int i=1;i<=m;i++) if(dp[(1<<m)-1][i]!=-1)ans=min(ans,dp[(1<<m)-1][i]); if(ans!=inf)printf("%d\n",ans); else printf("-1\n"); } return 0; }
标签:通道 res cstring sid cto when memset str next
原文地址:http://www.cnblogs.com/jhz033/p/7652754.html