martes, 22 de septiembre de 2009
10986 - Sending email
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <sstream>
using namespace std;
#define inf 1000000
void leer(int&a){
scanf("%d",&a);
}
int main(){
int test;
cin>>test;
for(int tt=1;tt<=test;tt++){
int n,m,s,t;
cin>>n>>m>>s>>t;
vector<vector<int> > adj(n);//adyacencia de vértices
vector<vector<int> > wadj(n);//los pesos de las aristas, este vector es inyectivo a adj
int a,b,c;
for(int i=0;i<m;i++){
leer(a);
leer(b);
leer(c);
adj[a].push_back(b);
adj[b].push_back(a);
wadj[a].push_back(c);
wadj[b].push_back(c);
}
vector<int> dist(n,inf);
dist[s]=0;
typedef pair<int,int> pii;
priority_queue<pii,vector<pii>,greater<pii> > q;
q.push(make_pair(0,s));
int res=-1;
while(!q.empty()){
int v=q.top().second;
int d=q.top().first;
q.pop();
if(dist[v]<d) continue;
if(v==t){res=d;break;}
for(int i=0;i<adj[v].size();i++){
int u=adj[v][i];
int nd=wadj[v][i]+d;
if(nd<dist[u]){
dist[u]=nd;
q.push(make_pair(nd,u));
}
}
}
cout<<"Case #"<<tt<<": ";
if(res==-1) cout<<"unreachable"<<endl;
else cout<<res<<endl;
}
}
10801 - Lift Hopping
// en cada piso, intentamos ir a todos los otros posibles pisos sin verificar //nada
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <sstream>
using namespace std;
#define inf 1000000
int main(){
int n,k;
while(cin>>n>>k){
vector<int> time(n);//la velocidad de cada elevador
for(int i=0;i<n;i++) cin>>time[i];
vector<vector<int> > elev(n);//este arreglo contiene todos los pisos accesables por el elevador i
vector<vector<int> > flo(100);//este arreglo contiene todos los elevadores que paran en el piso i
string cad;
getline(cin,cad); //para corregir la linea vacia
//se llenan todas las adyacencias
for(int i=0;i<n;i++){
getline(cin,cad);
istringstream is(cad);
int x;
while(is>>x){
elev[i].push_back(x);
flo[x].push_back(i);
}
}
//soluciones
vector<int> sol(100,inf);
sol[0]=0;
//estado: tiempo,piso
priority_queue<pair<int,int>,vector<pair<int,int> >,greater< pair<int,int> > > q;
q.push(make_pair(0,0));
int res=-1;
while(!q.empty()){
int fl=q.top().second;//piso actual
int tim=q.top().first;//tiempo actual
q.pop();
if(tim>sol[fl]) continue;//si este estado no tiene sentido
if(fl==k){res=tim;break;}//si se llegó a la solución
for(int i=0;i<flo[fl].size();i++){
int el=flo[fl][i];//elevador que llega al piso fl
for(int j=0;j<elev[el].size();j++){ //se intenta ir a todos los pisos accesables por este elevador, no se hace ninguna verificacion
int next=elev[el][j]; //siguiente piso
int ntime=tim+60+abs(next-fl)*time[el]; //nuevo tiempo
//ojo que el primer elevador que tomemos no tendrá penalidad de tiempo, eso lo vemos en el output
if(sol[next]>ntime){//si se relaja
sol[next]=ntime;
q.push(make_pair(ntime,next));
}
}
}
}
if(res==-1) cout<<"IMPOSSIBLE"<<endl;
else cout<<(k!=0?res-60:0)<<endl;//si k!=0, entonces, corregimos el tiempo por la penalidad que le pusimos al primer elevador
}
}
10099 The Tourist Guide
La solución se basa en la relajación max min para el maximum bottleneck problem
Se asume como elemento neutro de max a 0 y al elemento neutro de min como inf para
que son un bellman ford se resuelva esto en O(VE)
*/
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int N,R;
int test=1;
while(cin>>N>>R && N){
vector<pair<int,int> > edg(R);//aristas
vector<int> cap(R);//capacidades
for(int i=0;i<R;i++){
cin>>edg[i].first>>edg[i].second;
cin>>cap[i];
edg[i].first--;
edg[i].second--;
}
int s,d,p;
cin>>s>>d>>p;
s--;d--;
#define inf 1000000
vector<int> sol(N,0);
sol[s]=inf;
for(int i=0;i<N-1;i++){
//las aristas son bidireccionales
for(int j=0;j<R;j++){
int u=edg[j].first;
int v=edg[j].second;
int w=cap[j];
int a=min(sol[u],w);
int b=min(sol[v],w);
if(b>sol[u]) sol[u]=b;
if(a>sol[v]) sol[v]=a;
}
}
cout<<"Scenario #"<<test++<<endl;
int cant=sol[d]-1;//podemos llevar una persona menos que sol[d], ya que debemos viajar en el carro
cout<<"Minimum Number of Trips = "<<(p+cant-1)/cant<<endl<<endl;
}
}
658 - It's not a Bug, it's a Feature!
//(tiempo y bugs activos) se trata de ir a todos los otros posibles estados
//por medio de los patchs dados, con bitwise, si no, sale TLE
#include <vector>
#include <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
#define mp make_pair
int main(){
int n,m;
int best[1<<20];//arreglo donde se guardarán las mejores soluciones, recordar que para n bugs, hay 1<<n=2^n posibles estados
int test=1;//número de test
char aux;
while(cin>>n>>m && n!=0){
int completo=(1<<n)-1;//n bits en 1
//respectivamente para el patch i: inhas = lo que debe tener previamente | innhas = lo que no debe tener previamente |
//outadd= lo que se añade | outrest=lo que se quita
vector<int> inhas(m,0),innhas(m,0),outadd(m,0),outrest(m,completo);
vector<int> t(m); //los tiempos de cada patsh
//lectura
for(int i=0;i<m;i++){
cin>>t[i];
for(int j=0;j<n;j++){
cin>>aux;
if(aux=='-') innhas[i]|=1<<j;
else if(aux=='+') inhas[i]|=1<<j;
}
for(int j=0;j<n;j++){
cin>>aux;
if(aux=='+') outadd[i]|=1<<j;
else if(aux=='-') outrest[i]&=~(1<<j);
}
}
memset(best,-1,4*(1<<n));//se pone todo el espacio necesario en 1, se multiplica por 4 porque cada int son 4 bytes
// y metset copia una cantidad de bytes
int ini=completo;
best[ini]=0;//estado inicial
//estado de la cola de prioridad, un par: <tiempo acumulado, estado actual>
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
q.push(mp(0,ini));//se añade estado inicial
int res=-1;
while(!q.empty()){
int cost=q.top().first;
int state=q.top().second;
q.pop();
if(best[state]<cost) continue; //si este vértice es basura
if(state==0){res=cost;break;} //si es solución
//se intenta con todos los patchs
for(int i=0;i<m;i++){
//se verifica si el path i sirve
bool puede=true;
if((state&inhas[i])!=inhas[i]) puede=false;
else if((state&innhas[i])!=0) puede=false;
if(puede){
//se crea el siguiente estado
int next=state;
next|=outadd[i];
next&=outrest[i];
int ncost=cost+t[i];
//si el nuevo estado se relaja
if(best[next]==-1||best[next]>ncost){
best[next]=ncost;
q.push(mp(ncost,next));
}
}
}
}
cout<<"Product "<<test++<<endl;
if(res!=-1) cout<<"Fastest sequence takes "<<res<<" seconds."<<endl;
else cout<<"Bugs cannot be fixed."<<endl;
cout<<endl;
}
}
lunes, 21 de septiembre de 2009
10369 - Arctic Network
// distancias D, y para cada una de estas distancias calcular la cantidad de
// componentes conexos que quedan luego de intentar hacer un MST
// y según esta cantidad y la cantidad de satélites disponibles, verificar
// si cierto D cumple o no
#include
#include
#include
#include
#include
#include
using namespace std;
int p[500],rank[500];
void make_set(int x){
p[x]=x;
rank[x]=0;
}
void link(int x,int y){
if(rank[x]>rank[y])
p[y]=x;
else{
p[x]=y;
if(rank[x]==rank[y]){
rank[y]++;
}
}
}
int find_set(int x){
if(x!=p[x]){
p[x]=find_set(p[x]);
}
return p[x];
}
void Union(int x,int y){
link(find_set(x),find_set(y));
}
int S,P;
pair
vector<pair<double,pair<int,int> > > edg;
bool cumple(double D){
for(int i=0;i
sz=ss.size(); >pp[i].first>>pp[i].second; int dx=pp[i].first-pp[j].first;
int sz=edg.size();
for(int i=0;i
double w=edg[i].first;
int u=edg[i].second.first;
int v=edg[i].second.second;
if(find_set(u)!=find_set(v)){
if( w<D) Union(u,v);
else break;
}
}
set
for(int i=0;i
if(sz==1) return true;
if(sz<=S) return true;
else return false;
}
double solve(){
double izq=0;
double der=1e10;
while(fabs(der-izq)>1e-05){
double mid=(izq+der)/2;
if(cumple(mid)) der=mid;
else izq=mid;
}
return (izq+der)/2;
}
int main(){
int N;
cin>>N;
for(int tt=0;tt
cin>>S>>P;
for(int i=0;i
edg.resize(0);
for(int i=0;i
int dy=pp[i].second-pp[j].second;
double d=sqrt(dx*dx+dy*dy);
edg.push_back(make_pair(d,make_pair(i,j)));
}
sort(edg.begin(),edg.end());
double ret=solve();
printf("%.2lf\n",ret);
}
}
567 - Risk
#include
#include
#include
#include
#include
using namespace std;
int main(){
int m[20][20];
int r,x,tt=1;
while(cin>>r){
for(int i=0;i<20;i++) for(int j=0;j<20;j++) m[i][j]=i!=j?1000000:0;
for(int i=0;i<19;i++){
if(i>0) cin>>r;
for(int j=0;j
}
int n=20;
for(int k=0;k
cin>>r;
cout<<"Test Set #"<<
for(int i=0;i
int a,b;
cin>>a>>b;
printf("%2d to %2d:%2d\n",a,b,m[a-1][b-1]);
}
cout<
}
}
10397 - Connect the Campus
#include
#include
#include
#include
#include
using namespace std;
int p[750],rank[750];
//union find
void make_set(int x){
p[x]=x;
rank[x]=0;
}
void link(int x,int y){
if(rank[x]>rank[y])
p[y]=x;
else{
p[x]=y;
if(rank[x]==rank[y]){
rank[y]++;
}
}
}
int find_set(int x){
if(x!=p[x]){
p[x]=find_set(p[x]);
}
return p[x];
}
void Union(int x,int y){
link(find_set(x),find_set(y));
}
bool comp(pair
return A.first
}
int main(){
int n;
while(cin>>n){
double d;
vector
for(int i=0;i
vector
for(int i=0;i
for(int i=0;i
long long dy=pp[i].second-pp[j].second;
edg.push_back(make_pair(sqrt(dx*dx+dy*dy+0.0),make_pair(i,j)));
}
cin>>n;
for(int i=0;i
int u,v;cin>>u>>v;
Union(u-1,v-1);
}
sort(edg.begin(),edg.end(),comp);
double sum=0;
for(int i=0;i
int u,v;
d=edg[i].first;
u=edg[i].second.first;
v=edg[i].second.second;
if(find_set(u)!=find_set(v)){
Union(u,v);
sum+=d;
}
}
printf("%.2lf\n",sum);
}
}