洛谷 P2243 电路维修
题目背景
Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上。在她无依无靠的时候,善良的运输队员Mark 和James 收留了她。Elf 很感谢Mark和James,可是一直也没能给他们帮上什么忙。
题目描述
有一天 Mark 和James 的飞行车没有办法启动了,经过检查发现原来是电路板的故障。飞行车的电路板设计很奇葩,如下图所示:
输入输出格式
输入格式:
输入文件包含多组测试数据。第一行包含一个整数T 表示测试数据的数目。
对于每组测试数据,第一行包含正整数 R 和C,表示电路板的行数和列数。
之后 R 行,每行C 个字符,字符是"/"和"\"中的一个,表示标准件的方向。
对于40% 的数据,R,C≤5。
对于 100% 的数据,R,C≤500,T≤5。
输出格式:
对于每组测试数据,在单独的一行输出一个正整数,表示所需的缩小旋转次数。
如果无论怎样都不能使得电源和发动机之间连通,输出 NO SOLUTION。
输入输出样例
输入样例#1:
1
3 5
\\/\\
\\///
/\\\\
输出样例#1:
1
说明
样例的输入对应于题目描述中的情况。
只需要按照下面的方式旋转标准件,就可以使得电源和发动机之间连通。
思路:跑最短路。
错因:数组开小了,边数太多spfa会TLE应该用dijstra
60分代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 350010 using namespace std; char s[1010]; int t,r,c,tot; int vis[MAXN],dis[MAXN]; int to[MAXN*2],net[MAXN*2],cap[MAXN*2],head[MAXN*2]; void add(int u,int v,int w){ to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot; to[++tot]=u;net[tot]=head[v];cap[tot]=w;head[v]=tot; } void spfa(int s){ queue<int>que; memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); que.push(s); dis[s]=0;vis[s]=1; while(!que.empty()){ int now=que.front(); que.pop(); vis[now]=0; for(int i=head[now];i;i=net[i]) if(dis[to[i]]>dis[now]+cap[i]){ dis[to[i]]=dis[now]+cap[i]; if(!vis[to[i]]){ vis[to[i]]=1; que.push(to[i]); } } } } int main(){ scanf("%d",&t); while(t--){ tot=0; memset(head,0,sizeof(head)); scanf("%d%d",&r,&c); for(int i=1;i<=r;i++){ scanf("%s",s); for(int j=0;j<c;j++) if(s[j]=='/'){ add((i-1)*(c+1)+j+2,i*(c+1)+j+1,0); add((i-1)*(c+1)+j+1,i*(c+1)+j+2,1); } else{ add((i-1)*(c+1)+j+1,i*(c+1)+j+2,0); add((i-1)*(c+1)+j+2,i*(c+1)+j+1,1); } } spfa(1); if(dis[(r+1)*(c+1)]==0x3f3f3f3f) cout<<"NO SOLUTION"<<endl; else cout<<dis[(r+1)*(c+1)]<<endl; } }
AC代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 1050010 using namespace std; struct nond{ int number,dis; bool operator < (nond b) const{ return dis>b.dis; } }; char s[1010]; int t,r,c,tot; int dis[MAXN]; int to[MAXN*2],net[MAXN*2],cap[MAXN*2],head[MAXN*2]; void add(int u,int v,int w){ to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot; to[++tot]=u;net[tot]=head[v];cap[tot]=w;head[v]=tot; } void dijkstra(int s){ priority_queue<nond>que; memset(dis,0x3f,sizeof(dis)); que.push((nond){s,0}); dis[s]=0; while(!que.empty()){ nond now=que.top(); que.pop(); if(dis[now.number]!=now.dis) continue; for(int i=head[now.number];i;i=net[i]) if(dis[to[i]]>dis[now.number]+cap[i]){ dis[to[i]]=dis[now.number]+cap[i]; que.push((nond){to[i],dis[to[i]]}); } } } int main(){ scanf("%d",&t); while(t--){ tot=0; memset(head,0,sizeof(head)); scanf("%d%d",&r,&c); for(int i=1;i<=r;i++){ scanf("%s",s+1); for(int j=1;j<=c;j++) if(s[j]=='/'){ add((i-1)*(c+1)+j+1,i*(c+1)+j,0); add((i-1)*(c+1)+j,i*(c+1)+j+1,1); } else{ add((i-1)*(c+1)+j,i*(c+1)+j+1,0); add((i-1)*(c+1)+j+1,i*(c+1)+j,1); } } dijkstra(1); if(dis[(r+1)*(c+1)]==0x3f3f3f3f) cout<<"NO SOLUTION"<<endl; else cout<<dis[(r+1)*(c+1)]<<endl; } }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。