每条路长度为1,值为0或者1,走最短路,并且值最大。
spfa 并且记录路径。
入队的时候vis[x]没有等于1,tle了好久。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+55;
int head[maxn],to[maxn<<1],val[maxn<<1],nxt[maxn<<1],cnt=1,from[maxn<<1];
int pre[maxn];
struct ways
{
int u,v;
int flag;
int val;
}way[maxn];
void add(int u,int v,int va)
{
from[cnt]=u;
nxt[cnt]=head[u];
to[cnt]=v;
val[cnt]=va;
head[u]=cnt++;
}
int n ,m;
int vis[maxn],dis[maxn];
int maxval[maxn];
void spfa(int s,int t)
{
for(int i=1;i<=n;i++){
vis[i]=0;
maxval[i]=0;
dis[i]=inf;
}
dis[s]=val[s]=0;
queue<int>q;
q.push(1);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u]=0;
int va=maxval[u];
//if(dis[u]>dis[n]) break;
//if(u==n) continue;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i];
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
pre[v]=i;
maxval[v]=va+val[i];
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}else if(dis[v]==dis[u]+1&&maxval[v]<va+val[i]){
maxval[v]=va+val[i];
pre[v]=i;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}
int main()
{
memset(head,-1,sizeof head);
pre[1]=-1;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
int u,v,val;scanf("%d%d%d",&u,&v,&val);
way[i].u=u;
way[i].v=v;
way[i].val=val;
add(u,v,val);
add(v,u,val);
}
spfa(1,n);
int now = pre[n];
int ci=0;
while(now!=-1){
way[(now+1)/2].flag=1;
now=pre[from[now]];
}
int num=0;
for(int i=1;i<=m;i++){
if(way[i].flag==1&&way[i].val==0){
num++;
}
if(way[i].flag==0&&way[i].val==1){
num++;
}
}
printf("%d\n",num);
for(int i=1;i<=m;i++){
if(way[i].flag==1&&way[i].val==0){
printf("%d %d %d\n",way[i].u,way[i].v,way[i].val^1);
}
if(way[i].flag==0&&way[i].val==1){
printf("%d %d %d\n",way[i].u,way[i].v,way[i].val^1);
}
}
return 0;
}