結果
| 問題 | No.468 役に立つ競技プログラミング実践編 |
| コンテスト | |
| ユーザー |
kuuso1
|
| 提出日時 | 2016-12-10 03:23:56 |
| 言語 | C#(csc) (csc 3.9.0) |
| 結果 |
AC
|
| 実行時間 | 483 ms / 2,000 ms |
| コード長 | 5,914 bytes |
| 記録 | |
| コンパイル時間 | 1,061 ms |
| コンパイル使用メモリ | 108,160 KB |
| 実行使用メモリ | 62,952 KB |
| 最終ジャッジ日時 | 2024-11-30 01:34:51 |
| 合計ジャッジ時間 | 8,051 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 31 |
| other | AC * 6 |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
class TEST{
static void Main(){
Sol mySol =new Sol();
mySol.Solve();
}
}
class Sol{
public void Solve(){
int[] InDeg = new int[N];
for(int i=0;i<N;i++){
foreach(var nxt in E[i]) InDeg[nxt.Pos]++;
}
// Debug.Assert( InDeg[0] == 0 );
// Debug.Assert( InDeg.Skip(1).Select(x => x !=0).Aggregate(true, (b,y) => b&y ) );
int[] ENT = new int[N]; // Earliest Node Time
for(int i=0;i<N;i++) ENT[i] = -1;
ENT[0] = 0;
Queue<int> Q = new Queue<int>();
Q.Enqueue(0);
while(Q.Count>0){
var now = Q.Dequeue();
foreach(var nxt in E[now]){
InDeg[nxt.Pos]--;
if(InDeg[nxt.Pos] == 0){
Q.Enqueue(nxt.Pos);
}
ENT[nxt.Pos] = Math.Max(ENT[nxt.Pos], ENT[now] + nxt.Cost);
}
}
int[] OutDeg = new int[N];
int[] LNT = new int[N]; // Latest Node Time
for(int i=0;i<N;i++) LNT[i] = int.MaxValue;
LNT[N-1] = ENT[N-1];
Q = new Queue<int>();
Q.Enqueue(N-1);
while(Q.Count>0){
var now = Q.Dequeue();
foreach(var rev in XE[now]){
OutDeg[rev.Pos]++;
if(OutDeg[rev.Pos] == E[rev.Pos].Count){
Q.Enqueue(rev.Pos);
}
LNT[rev.Pos] = Math.Min(LNT[rev.Pos], LNT[now] - rev.Cost);
}
}
// Debug.Assert( OutDeg[N-1] == 0 );
// Debug.Assert( OutDeg.Zip(E,(n,p) => n == p.Count).Aggregate(true, (b,y) => b&y ) );
// Debug.Assert( ENT.Zip(LNT,(e,l) => e > l).Count( b => b ) == 0);
//Console.WriteLine(String.Join(" ",ENT));
//Console.WriteLine(String.Join(" ",LNT));
//int marginPersonCount = ENT.Zip(LNT,(e,l) => l > e).Count( b => b );
int marginPersonCount = 0;
for(int i=0;i<N;i++) if(ENT[i] < LNT[i]) marginPersonCount++;
Console.WriteLine("{0} {1}/{2}",ENT[N-1],marginPersonCount,N);
}
int N,M;
List<Pair>[] E;
List<Pair>[] XE;
public Sol(){
// read input
using(var r = new FastIn(1000000)){
N = r.ReadInt(); M = r.ReadInt();
E = new List<Pair>[N];
for(int i=0;i<N;i++) E[i] = new List<Pair>();
XE = new List<Pair>[N];
for(int i=0;i<N;i++) XE[i] = new List<Pair>();
for(int i=0;i<M;i++){
int a = r.ReadInt();
int b = r.ReadInt();
int c = r.ReadInt();
E[a].Add(new Pair(b,c));
XE[b].Add(new Pair(a,c));
}
}
}
class Pair{
public int Pos,Cost;
public Pair(int pos, int cost){
Pos = pos; Cost = cost;
}
}
}
class FastIn:IDisposable {
int Size;
byte[] Mem;
int ptr;
int rsize;
bool unfinished;
Stream stdin;
void Init(int n) {
Size = n;
Mem = new byte[Size];
rsize=(stdin=Console.OpenStandardInput()).Read(Mem, 0, Size);
ptr = 0;
unfinished=(rsize == Size);
}
void Next() {
if (unfinished == false) return;
rsize=stdin.Read(Mem, 0, Size);
ptr = 0;
unfinished = (rsize == Size);
}
~FastIn(){
stdin.Dispose();
}
void IDisposable.Dispose(){
stdin.Dispose();
}
public void Dispose(){
stdin.Dispose();
}
public FastIn() {
Init(100000);
}
public FastIn(int n) {
Init(n);
}
public int ReadInt() {
int ret = 0;
int sig = 1;
while (ptr < rsize && Mem[ptr] != ' ' && Mem[ptr] != '\n' && Mem[ptr] != '\r' ) {
if(ret==0 && Mem[ptr] == '-'){
sig *= -1; ptr++; continue;
}
ret = ret * 10 + Mem[ptr++] - '0';
if (ptr == Size) Next();
}
while (ptr < rsize && (Mem[ptr] == ' ' || Mem[ptr] == '\n' || Mem[ptr] == '\r') ) {
ptr++;
if (ptr == Size) Next();
}
return ret*sig;
}
public double ReadDouble() {
double ret = 0;
double sig = 1;
bool dot = false;
double keta = 0.1;
while (ptr < rsize && Mem[ptr] != ' ' && Mem[ptr] != '\n' && Mem[ptr] != '\r' ) {
if(ret==0 && Mem[ptr] == '-'){
sig *= -1; ptr++;
if (ptr == Size) Next();
continue;
}
if(Mem[ptr] == '.'){
dot = true;
ptr++;
if (ptr == Size) Next();
continue;
}
if(!dot){
ret = ret * 10 + Mem[ptr++] - '0';
if (ptr == Size) Next();
}else{
ret = ret + (Mem[ptr++] - '0')*keta;
keta /= 10.0;
if (ptr == Size) Next();
}
}
while (ptr < rsize && (Mem[ptr] == ' ' || Mem[ptr] == '\n' || Mem[ptr] == '\r') ) {
ptr++;
if (ptr == Size) Next();
}
return ret*sig;
}
public uint ReadUint() {
uint ret = 0;
uint sig = 1;
while (ptr < rsize && Mem[ptr] != ' ' && Mem[ptr] != '\n' && Mem[ptr] != '\r' ) {
ret = ret * 10 + Mem[ptr++] - '0';
if (ptr == Size) Next();
}
while (ptr < rsize && (Mem[ptr] == ' ' || Mem[ptr] == '\n' || Mem[ptr] == '\r') ) {
ptr++;
if (ptr == Size) Next();
}
return ret*sig;
}
public long ReadLong() {
long ret = 0;
long sig = 1;
while (ptr < rsize && Mem[ptr] != ' ' && Mem[ptr] != '\n' && Mem[ptr] != '\r' ) {
if(ret==0 && Mem[ptr] == '-'){
sig *= -1; ptr++; continue;
}
ret = ret * 10 + Mem[ptr++] - '0';
if (ptr == Size) Next();
}
while (ptr < rsize && (Mem[ptr] == ' ' || Mem[ptr] == '\n' || Mem[ptr] == '\r') ) {
ptr++;
if (ptr == Size) Next();
}
return ret*sig;
}
public String ReadStr() {
//2byte文字はNG
StringBuilder sb = new StringBuilder();
while (ptr < rsize && Mem[ptr] != ' ' && Mem[ptr] != '\n' && Mem[ptr] != '\r') {
sb.Append((char)Mem[ptr++]);
if (ptr == Size && unfinished) Next();
}
while (ptr < rsize && (Mem[ptr] == ' ' || Mem[ptr] == '\n' || Mem[ptr] == '\r') ) {
ptr++;
if (ptr == Size && unfinished) Next();
}
return sb.ToString();
}
public String ReadLine() {
//極力使わない(split/parseするくらいなら上をつかう)
StringBuilder sb = new StringBuilder();
while (ptr < rsize && Mem[ptr] != '\n' && Mem[ptr] != '\r') {
sb.Append((char)Mem[ptr++]);
if (ptr == Size && unfinished) Next();
}
while (ptr < rsize && (Mem[ptr] == ' ' || Mem[ptr] == '\n' || Mem[ptr] == '\r')) {
ptr++;
if (ptr == Size && unfinished) Next();
}
return sb.ToString();
}
}
kuuso1