想了好多种划分连通块的方法, 总感觉差点意思,无奈去翻题解,发现有一篇题解挺对我的胃口,然后就仿着那篇题解写。 RE后我又回去对着题解检查了一遍,然后交了还是RE,为啥?
#include <bits/stdc++.h>
using namespace std;
int n,m;
const int maxn=1e5+5;
const int maxm=2e5+5;
int head[maxn*2],cnt;
struct edge{int to,pre,val,col;}line[maxn*2+maxm];
void addline(int u,int v,int value,int com)
{
cnt++;
line[cnt].to=v;
line[cnt].pre=head[u];
line[cnt].col=com;
line[cnt].val=value;
head[u]=cnt;
}
int extra;
struct node{
int pos;
long long d;
friend bool operator<(const node &x,const node &y)
{
return x.d>y.d;
}
};
priority_queue<node>q;
bool vis[maxn*2];
long long dis[maxn*2];
void dij()
{
memset(dis,0x3f,sizeof(dis));
q.push((node){1,1});
dis[1]=0;
while(!q.empty())
{
node top=q.top();
q.pop();
int temppos=top.pos;
if(vis[temppos])
continue;
vis[temppos]=1;
for(int i=head[temppos];i;i=line[i].pre)
{
int v=line[i].to;
if(dis[v]>dis[temppos]+line[i].val && !vis[v])
{
dis[v]=dis[temppos]+line[i].val;
q.push((node){v,dis[v]});
}
}
}
}
int last[maxn*2],del[maxn*2];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
extra=n;
for(int i=1;i<=m;i++)
{
int u,v,c;
cin>>u>>v>>c;
addline(u,++extra,1,c);
addline(extra,v,1,0);
addline(v,extra,1,c);
addline(extra,u,1,0);
}
int cnt_del;
for(int i=1;i<=n;i++)
{
cnt_del=0;
for(int j=head[i];j;j=line[j].pre)
{
int color=line[j].col;
if(last[color])
{
addline(line[j].to,last[color],0,color);
addline(last[color],line[j].to,0,color);
}
else
del[++cnt_del]=color;
last[color]=line[j].to;
}
for(int j=1;j<=cnt_del;j++)
last[del[j]]=0;
}
dij();
if(dis[n]==dis[0])
cout<<-1;
else
cout<<(dis[n]>>1);
return 0;
}